提问人:wenxi wang 提问时间:11/17/2023 最后编辑:wenxi wang 更新时间:11/17/2023 访问量:74
与引用匹配的 C++ 模板类型 [重复]
c++ template type matching with references [duplicate]
问:
当我运行以下代码时,发生错误。
#include <iostream>
using namespace std;
class M {
public:
M(): a(0), b(0) {}
M(int a, int b): a(a), b(b) {}
private:
int a;
int b;
};
template <typename T>
class Test {
public:
Test(const T& my) { }
T my_;
};
template <typename T>
using ReferTest = Test<T&>;
int main()
{
ReferTest<M> t2(M(3,4));
}
错误是:
main.cpp: In function ‘int main()’:
main.cpp:25:20: error: cannot bind non-const lvalue reference of type ‘M&’ to an rvalue of type ‘M’
25 | ReferTest<M> t2(M(3,4));
| ^~~~~~
main.cpp:16:17: note: initializing argument 1 of ‘Test<T>::Test(const T&) [with T = M&]’
16 | Test(const T& my) { }
| ~~~~~~~~~^~
“无法将类型为'M&'的非常量左值引用绑定到类型为'M'的右值”让我感到困惑,我知道M(3,4)是一个右值,但是Test构造函数中的类型是“const T&”,而不是“non-const”。
答:
0赞
Pepijn Kramer
11/17/2023
#1
我认为您应该在模板中使用转发引用,而不是像这样的 const&,然后复制临时引用。使用像您这样的临时对象的引用充其量是棘手的。
#include <iostream>
// don't use using namespace std;
class M
{
public:
M(): a(0), b(0) {}
M(int a, int b): a(a), b(b) {}
~M(){ std::cout << "deleting M\n"; }
int get_a() const noexcept { return a; };
private:
int a;
int b;
};
template <typename T>
class Test {
public:
Test(T&& my) : // <== forwarding here
my_{std::forward<T>(my) }
{
}
T my_;
};
template <typename T>
using ReferTest = Test<T>; // <== no reference here!
int main()
{
ReferTest<M> t2(M{3,4}); // <== M's temporary will be deleted after this line! So it is not safe to have a reference to it after this line.
std::cout << t2.my_.get_a();
}
评论
const T&
T=M&
T const&
template <typename T> using ReferTest = Test<T&>;
const
Test::my_
Test<int&> t2(1);