【问题标题】:non-static data member initialization with new expression使用新表达式初始化非静态数据成员
【发布时间】:2015-08-13 07:50:26
【问题描述】:

考虑以下代码:

#include <map>

template <typename T>
struct X {
    std::map<int, T>* storage = new std::map<int, T>();
};

int main() {
    X<int> x;
}

这在clang 3.6.0 上编译,但在gcc 5.1 上编译失败。但是,如果 storage 的类型改为 std::vector&lt;T&gt;*(或只是 T*),它将编译。

我相当确定这是 gcc 的编译器错误(编辑:我将其提交为 66344),但我想我会要求确保:上面的示例是否有任何原因应该t 编译?

gcc 编译错误:

main.cpp:5:51: error: expected ';' at end of member declaration    
     std::map<int, T>* storage = new std::map<int, T>();    
                                                   ^    

main.cpp:5:51: error: declaration of 'std::map<int, T> X<T>::T'    
main.cpp:3:11: error:  shadows template parm 'class T'    
 template <typename T>    
           ^

main.cpp:5:52: error: expected unqualified-id before '>' token    
     std::map<int, T>* storage = new std::map<int, T>();    
                                                    ^    
main.cpp:5:46: error: wrong number of template arguments (1, should be at least 2)    
     std::map<int, T>* storage = new std::map<int, T>();    
                                              ^

In file included from /usr/local/include/c++/5.1.0/map:61:0,    
                 from main.cpp:1:    
/usr/local/include/c++/5.1.0/bits/stl_map.h:96:11: note: provided for 'template<class _Key, class _Tp, class _Compare, class _Alloc> class std::map'    
     class map    
           ^

【问题讨论】:

  • 只是为了确定:您使用的是gcc 还是g++?我经常把它混在一起......
  • @atlaste g++ 4.9.2 也不编译这个。
  • @atlaste 老兄,显然我们使用的是 C++ 编译器 - 如果我们使用的是 C 编译器,它会抱怨这段代码中的各种其他内容。
  • 解决方法:使用 braced-init-list 来规避 g++ => template &lt;typename T&gt; struct X { std::map&lt;int, T&gt;* storage { new std::map&lt;int, T&gt; () }; };的(错误)行为>
  • @FilipRoséen-refp,G++ 没有故障,它符合标准,请参阅open-std.org/JTC1/SC22/WG21/docs/cwg_active.html#325(尽管使用花括号初始化列表是一种有效的解决方法)

标签: c++ c++11 gcc language-lawyer


【解决方案1】:

这是Core issue 325 中描述的问题的另一个示例(参见“Notes from the August, 2011 meeting”,其中有一个非常相似的示例),即模板参数列表中的逗号导致解析失败,当编译器尝试确定表达式的结尾在哪里。

这个问题仍然悬而未决,但委员会的共识是应该让它发挥作用(我不知道会做出什么改变以使其有效)。

Clang 已经实施了一段时间的解决方法(可能会暂时解析表达式并在失败时重试),而 Nathan Sidwell 只有 un-suspended the relevant G++ bug and assigned it to himself,所以我希望他计划尽快修复它。

【讨论】:

  • 核心问题 325 似乎与默认参数有关
  • @sp2danny,继续阅读,请参阅“2011 年 8 月会议的笔记”,其中有一个非常相似的示例
【解决方案2】:

有趣,它应该可以在 IMO 中使用。

这个确实编译:

#include <map>

template <typename T>
struct X {
   typedef std::map<int, T> mt;
   mt *storage = new mt();
};

int main() {
        X<int> x;
}

显然模板参数扩展出了点问题...

编译:

g++ -o test test.cpp -std=c++11

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-02
    • 1970-01-01
    • 2011-08-04
    • 1970-01-01
    • 1970-01-01
    • 2014-09-01
    • 1970-01-01
    相关资源
    最近更新 更多