c++ - gcc 4.7 有时无法使用指针模板参数

标签 c++ templates gcc c++11 compiler-bug

完整(非)工作示例:

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 ‘&’ operand
constexpr.cpp:9:16: error: could not convert template argument ‘(const s*)(& s_objs)’ to ‘const s*’

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

最佳答案

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

我在 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;
}

我也在 gcc 4.8.1 上工作 without启用 C++11。

因此,解决方法是:

改变

constexpr const s s_objs[] = ...;

extern const s s_objs[] = ...;

Live example here .

如果你想让变量是一个静态类成员,那么你必须指定它有外部链接:

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

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

这给了我一个 warning on gcc 4.7 ,而不是 4.8。还有它doesn't compile on Rise4Fun .所以,我不确定这是纯标准还是某个编译器中的错误。

关于c++ - gcc 4.7 有时无法使用指针模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21598561/

相关文章:

c++ - 如何编译qtwebkit插件?

c++ - 在 C++ 中引发异常和处理某些异常类型的正确方法是什么

c++ - 如何在函数模板中声明模板特化?

gcc - OpenCL,这是正常的执行时间吗?

c - 在 C 中打印字节数组时处理神秘输出

c++ - 使用C++确定三个数中最大的数

c# - 颠覆以更新文本文件中的版本

C++模板和重载运算符

c++ - 如果不键入别名类型的完整声明,则无法从单独文件中的类模板定义访问类型别名

c++ - 为什么 c++11 上的 std::list 更大?