2

完整(不)工作示例:

struct s { int i; };

template<const s* _arr>
class struct_array
{
public:
    static constexpr auto arr = _arr[0]; // works
    template<int >
    struct inner // line 9, without this struct, it works
    {    
    };
};

constexpr const s s_objs[] = {{ 42 }};

int main()
{
    struct_array<s_objs> t_obj;
    return 0;
}

编译如下:

g++ -std=c++11 -Wall constexpr.cpp -o constexpr

我用 ideone 的 gcc 4.8.1 得到了一个正在运行的程序,但是 4.7.3 向我打印了这个:

constexpr.cpp: In instantiation of ‘class struct_array<((const s*)(& s_objs))>’:
constexpr.cpp:18:30:   required from here
constexpr.cpp:9:16: error: lvalue required as unary ‘&amp;’ operand
constexpr.cpp:9:16: error: could not convert template argument ‘(const s*)(& s_objs)’ to ‘const s*’

最后两行重复 3 次。原因是什么,是否有任何解决方法可以在 gcc 4.7.3 上使用我的代码?

4

1 回答 1

1

这对我来说似乎是一个编译器错误。

我在 gcc 4.1.2 ( codepad ) 上尝试了您的示例,您必须明确指出该变量具有外部链接(除非另有说明,否则 const 表示内部链接,以下代码是 C++03):

struct s { int i; };

template<const s* _arr>
class struct_array
{
public:
    static const s arr;
    template<int >
    struct inner
    {    
    };
};

template<const s* _arr>
const s struct_array<_arr>::arr = _arr[0];

// Notice the 'extern'
extern const s s_objs[] = {{ 42 }};

int main()
{
    struct_array<s_objs> t_obj;
    return 0;
}

我也让它在没有启用 C++11 的 gcc 4.8.1 上工作。

因此,解决方法是:

改变

constexpr const s s_objs[] = ...;

extern const s s_objs[] = ...;

现场示例在这里

如果您希望变量成为静态类成员,则必须将其指定为具有外部链接:

struct data
{
    static const s s_objs[1];
};

extern const s data::s_objs[1] = {{ 42 }};

这给了我关于 gcc 4.7 的警告,而不是 4.8 的警告。它也不能在 Rise4Fun 上编译。因此,我不确定这是纯标准还是其中一个编译器中的错误。

于 2014-02-06T15:00:08.093 回答