【问题标题】:c++ static int def in doubly nested template class fails with clang++ and g++双重嵌套模板类中的c ++ static int def因clang ++和g ++而失败
【发布时间】:2016-06-20 22:48:17
【问题描述】:

使用以下代码:

struct my_symbols {
  enum class syms { symb_0_0, symb_0_1 };
};
template
< typename SymbolEnums
>
struct outer {
  using syms_0 = typename SymbolEnums ::syms;
  template <syms_0 AnSym0, int Int>
  struct inner {
    static int const val;
  };
};

template 
< typename SymbolEnums
>
template 
< typename outer<SymbolEnums>::syms_0 AnSym0
, int Int
>
int const outer<SymbolEnums>::inner<AnSym0, Int>::val = Int;

int main() {
  return 
      outer<my_symbols>::
      inner<my_symbols::syms::symb_0_1, 1>::val;
}

我明白了,使用 gcc5.2.0:

非模板‘int outer_tmpl::inner_tmpl::val’的模板定义 值=整数; ^

使用 clang3.8.0,我得到:

嵌套名称说明符'outer_tmpl::inner_tmpl::' 声明不引用类、类模板或类模板部分特化 值=整数; ^

如何更正代码?

TIA。

【问题讨论】:

    标签: c++ templates static nested


    【解决方案1】:

    我不完全知道为什么发布的代码不起作用。我怀疑答案深藏在 C++ 标准名称查找规则中,这些规则非常复杂——当然,假设这实际上不是编译器错误。这里的其他人可能知道。

    以下“等效”示例在 GCC 5.2.0 和 Clang 3.8 上编译。它们可能适合也可能不适合您的情况。

    示例 1:使用 constexpr 和类内初始化

    struct my_symbols {
      enum class syms { symb_0_0, symb_0_1 };
    };
    
    template<typename SymbolEnums>
    struct outer {
    
      using syms_0 = typename SymbolEnums::syms;
    
      template <syms_0 AnSym0, int Int>
      struct inner {
        static constexpr int val = Int;
      };
    };
    
    int main() {
      return outer<my_symbols>::inner<my_symbols::syms::symb_0_1, 1>::val;
    }
    

    示例 2:调整嵌套模板类型参数

    struct my_symbols {
      enum class syms { symb_0_0, symb_0_1 };
    };
    
    template<typename SymbolEnums>
    struct outer {
    
      using syms_0 = typename SymbolEnums::syms;
    
      template <syms_0 AnSym0, int Int>
      struct inner {
        static int const val;
      };
    };
    
    template<typename SymbolEnums>
    template<typename SymbolEnums::syms AnSym0, int Int>
    //       ^^^^^^^^^^^^^^^^^^^^^^^^^^
    int const outer<SymbolEnums>::inner<AnSym0, Int>::val = Int;
    
    int main() {
      return outer<my_symbols>::inner<my_symbols::syms::symb_0_1, 1>::val;
    }
    

    【讨论】:

    • 非常感谢巴雷特。因此,您只需使用 SymbolEnums::syms,而不是使用嵌套的 syms_0。就像你说的那样,这可能是语言中的错误或一些晦涩的规则:(
    猜你喜欢
    • 2019-04-28
    • 2022-06-24
    • 2021-12-29
    • 2021-11-21
    • 2012-12-28
    • 2017-02-05
    • 1970-01-01
    • 2013-02-19
    • 1970-01-01
    相关资源
    最近更新 更多