seg*_*ult 0 c++ inheritance templates c++17
我有一个相当大的类,它被减少到下面的最小失败示例:
#include <vector>
template <typename T> class Base {
public:
Base(std::vector<T> &&other) : map{other} {}
private:
const std::vector<T> map;
};
template <typename T> class Derived : public Base<T> {
public:
Derived(std::vector<T> &&other) : Base<T>{other} {}
};
int main() {
Derived<double>(std::vector<double>{1,2,3});
}
Run Code Online (Sandbox Code Playgroud)
当我运行这个时,我得到
$ clang++ -std=c++17 -O3 main.cpp && ./a.out
main.cpp:13:37: error: no matching constructor for initialization of 'Base<double>'
Derived(std::vector<T> &&other) : Base<T>{other} {}
^ ~~~~~~~
main.cpp:17:3: note: in instantiation of member function 'Derived<double>::Derived' requested here
Derived<double>(std::vector<double>{1,2,3});
^
main.cpp:3:29: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'std::vector<double>' to 'const Base<double>' for 1st argument
template <typename T> class Base {
^
main.cpp:3:29: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'std::vector<double>' to 'Base<double>' for 1st argument
template <typename T> class Base {
^
main.cpp:5:3: note: candidate constructor not viable: no known conversion from 'std::vector<double>' to 'std::vector<double> &&' for 1st argument
Base(std::vector<T> &&other) : map{other} {}
^
1 error generated.
Run Code Online (Sandbox Code Playgroud)
我不明白为什么这会给我一个编译错误。我希望Base<T>{other}在第 13 行调用第 5 行的构造函数,因为我传入的other是 inDerived的构造函数参数中声明为右值 ( std::vector<T> && other)的构造函数。但是,编译器说它是一个左值 ( std::vector<double>)。
因为我传入了在 Derived 的构造函数参数中声明为右值的 other (std::vector && other)
实际上,在 的范围内Derived(std::vector<T> &&other),other是一个左值,其类型是右值引用。这是一个常见的混淆点。看看强大的cppreference:
以下表达式是左值表达式:
- 变量、函数、模板参数对象(C++20 起)或数据成员的名称,无论类型如何,例如 std::cin 或 std::endl。即使变量的类型是 rvalue reference,由其名称组成的表达式也是一个左值表达式;
您需要other通过std::move()inDerived的构造函数显式转换为右值:
template <typename T> class Derived : public Base<T> {
public:
Derived(std::vector<T> &&other) : Base<T>{std::move(other)} {}
};
Run Code Online (Sandbox Code Playgroud)