【发布时间】:2021-08-09 05:01:21
【问题描述】:
我有一个相当大的课程,它被减少到下面的最低失败示例:
#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});
}
当我运行它时,我得到了
$ 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.
我不明白为什么这会给我一个编译错误。我希望第 13 行的 Base<T>{other} 调用第 5 行的构造函数,因为我传入了 other,它在 Derived 的构造函数参数中声明为右值 (std::vector<T> && other)。但是,编译器说它是一个左值 (std::vector<double>)。
【问题讨论】:
-
Base(std::vector<T> &&other) : map{std::move(other)} {}可能会更符合预期。 -
这也有效。我只是好奇为什么编译器似乎删除了右值。标准中是否有说明这种行为是可以预期的?
-
如果它有一个名字(比如...
other),那么它不是右值,除非你使用std::move将它“转换”为右值。void Foo(Bar&&)正在请求一个右值,Foo(std::move(bar))正在授予将其用作右值的权限,但直到m_bar = std::move(bar);才真正发生在 Foo 例程中。
标签: c++ templates inheritance c++17