我试图找出这段代码的错误。基本上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<int>'
? Gcc希望将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)) {}
^
答案 0 :(得分:1)
您无法在构造函数初始值设定项列表中初始化基类成员。
在Standardese中,T::value(std::move(arg.value))
中的type2(T&& arg) : T::value(std::move(arg.value)) {}
称为 mem-initializer ,T::value
称为 mem-initializer-id 。根据{{3}},
除非 mem-initializer-id 命名构造函数的类,构造函数类的非静态数据成员,或该类的直接或虚拟基类, mem-initializer 格式不正确。
您可以调用基类的构造函数,并让它初始化该成员。在这种特定情况下,您只需将T::value(std::move(arg.value))
更改为T(std::move(arg.value))
即可。 [class.base.init]p2