【问题标题】:C++ Member variable initialization in templated inherited class模板化继承类中的 C++ 成员变量初始化
【发布时间】:2016-08-11 01:44:24
【问题描述】:

我试图找出这段代码有什么问题。基本上type2 继承自type1<T>, type1<T2>,我想从基类之一初始化value 成员。

#include <utility>

template <typename T>
struct type1 {
    using base_type = T;

    template <typename... Args> type1(Args&&... args) : value(std::forward<Args>(args)...) {}

    T value;
};

template <typename... Ts>
struct type2 : public Ts... {
    template <typename T>
    type2(T&& arg) : T::value(std::move(arg.value)) {}
};

int main()
{
    type2<type1<int>, type1<double>> x(type1<int>(10));
    return 0;
}

但我从 clang 收到以下错误:

    Error(s):

source_file.cpp:15:25: error: typename specifier refers to non-type member 'value' in 'type1<int>'
    type2(T&& arg) : T::value(std::move(arg.value)) {}
                        ^~~~~
source_file.cpp:20:38: note: in instantiation of function template specialization 'type2<type1<int>, type1<double> >::type2<type1<int> >' requested here
    type2<type1<int>, type1<double>> x(type1<int>(10));
                                     ^
source_file.cpp:9:7: note: referenced member 'value' is declared here
    T value;
      ^
1 error generated.

为什么clang说typename specifier refers to non-type member 'value' in 'type1&lt;int&gt;'? Gcc 想要将(可能也是 clang)value 视为一种类型:

Error(s):

source_file.cpp: In instantiation of ‘type2<Ts>::type2(T&&) [with T = type1<int>; Ts = {type1<int>, type1<double>}]’:
source_file.cpp:20:54:   required from here
source_file.cpp:15:51: error: no type named ‘value’ in ‘struct type1<int>’
     type2(T&& arg) : T::value(std::move(arg.value)) {}
                                                   ^

【问题讨论】:

    标签: c++ compiler-errors c++14 variadic-templates template-meta-programming


    【解决方案1】:

    您不能在构造函数初始化列表中初始化基类的成员。

    在 Standardese 中,type2(T&amp;&amp; arg) : T::value(std::move(arg.value)) {} 中的 T::value(std::move(arg.value)) 称为 mem-initializerT::value 称为 mem-initializer-id。根据[class.base.init]p2

    除非 mem-initializer-id 命名构造函数的类、构造函数类的非静态数据成员或该类的直接或虚拟基类,否则 mem-initializer 格式不正确。

    你可以调用基类的构造函数,让它初始化成员。在这种特定情况下,您只需将T::value(std::move(arg.value)) 更改为T(std::move(arg.value))Demo.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-31
      • 1970-01-01
      • 2011-06-16
      • 2021-08-07
      • 2018-01-21
      • 1970-01-01
      • 2016-07-22
      • 2012-08-23
      相关资源
      最近更新 更多