Опитвам се да предам указател на масив от struct
s като аргумент за шаблон. Успях да го направя след известно време:
struct something{};
constexpr const something single;
constexpr const something array[12];
template<const something* arg> void f() {}
template<typename T>
constexpr T* workaround(T* v){
return v;
};
void bind(){
f<&single>(); //OK
f<array>(); //NO
f<&array>(); //NO
f<&array[0]>(); //NO
f<workaround(array)>(); //NO
f<(const something*)array>(); //OK
}
Дали това е един от редките случаи, когато масивът не може да се използва прозрачно като указател, или това е грешка в компилатора?
Отговори:
1 за отговор № 1Наистина вярвам, че най-простата форма на обаждането, f<array>();
, работи, само ако декларирате-дефинирате array
правилно:
struct Elem
{ };
constexpr const Elem array[5] { {} , {} , {} , {} , {} };
template<const Elem* arg> void f()
{ }
int main()
{
f<array>();
return 0;
}
Единственото нещо, което промених (освен редуциране на масива от 12 до 5 елемента) е да добавя инициализатор за array
.
(Това се компилира за мен, използвайки GCC 4.7.2.)
1 за отговор № 2
Заобикаляйки това с Apple clang v4.1, аз дойдох до кода по-долу, който компилира. Трябва да призная, че не знам дали е правилно Clang да настоява за външна връзка за single
и array
, Също така се основава на модификации на jogojapan без особена причина.
struct Elem {};
extern const Elem single;
extern const Elem array[3];
constexpr const Elem single {};
constexpr const Elem array[3] {{},{},{}};
template<const Elem* arg> void f()
{ }
int main()
{
f<&single>();
f<array>();
return 0;
}
FWIW, пристигнах на този изстрел в тъмното след препъване в това: http://lists.apple.com/archives/xcode-users/2006/Jun/msg00799.html