C++ 作为模板参数的结构数组

C++ 作为模板参数的结构数组,c++,templates,c++11,typetraits,C++,Templates,C++11,Typetraits,我试图将指向structs数组的指针作为模板参数传递。过了一会儿,我终于做到了: 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){ retur

我试图将指向
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
}
struct something{};
constexpr const单一事物;
constexpr const something数组[12];
模板void f(){}
模板
constexpr T*解决方案(T*v){
返回v;
};
无效绑定(){
f();//好的
f();//否
f();//否
f();//否
f();//否
f();//好的
}

这是数组不能透明地用作指针的罕见情况之一,还是编译器错误?

我实际上相信调用的最简单形式是
f()数组
,则代码>,不起作用:

struct Elem
{ };

constexpr const Elem array[5] { {} , {} , {} , {} , {} };

template<const Elem* arg> void f()
{ }

int main()
{
  f<array>();
  return 0;
}
结构元素 { }; constexpr常量元素数组[5]{{},{},{},{},{},{}; 模板void f() { } int main() { f(); 返回0; }
我唯一改变的事情(除了将数组从12个元素减少到5个元素之外)是为
array
添加一个初始值设定项


(这是为我编译的,使用GCC4.7.2。)

在Apple clang v4.1中玩弄这一点,我得到了下面的编译代码。我必须承认,我不知道对于
单个
数组
坚持外部链接是否正确。此外,基于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;
}
struct Elem{};
外部常量单一;
外部常量数组[3];
constexpr constelem single{};
constexpr常量元素数组[3]{{},{},{};
模板void f()
{ }
int main()
{
f();

f

你尝试过数组指针吗?FWIW,Apple clang v4.1(clang v3.1)不会编译大部分内容。对于初学者来说,它拒绝默认初始化
single
array
,因为
something
没有用户定义的默认构造函数。当我修改它时,它们就被初始化了(即
constexpr constelem single{}
)它拒绝调用
f
报告的所有变体:“已忽略候选模板:为模板参数'arg'显式指定的参数无效”为什么初始化在这里很重要?@LorenzoPistone因为
array
是一个常量表达式,编译器在计算模板时需要它的定义。定义是由初始化提供的。缺少初始化是GCC唯一感到困惑的事情。但是
f()
不应该工作。@LorenzoPistone True。事实上,我前面的注释不太符合逻辑。数组项的实际值(由初始化提供)应该没有必要。我无法解释为什么它对GCC很重要,但我想知道,如果不是通过初始化,您将如何为
const
对象的
constepr
数组赋值?