4
以下安全吗?在第一个类成员初始化之后,std::string
不会是move
d吗?它打印出来确定,但我不确定。转发可变参数模板参数给几个类成员
template <typename T>
class Test
{
public:
template <typename... Args>
Test(Args&&... args)
: m_one(new T(std::forward<Args>(args)...)),
m_two(new T(std::forward<Args>(args)...)) // <- Here
{
}
private:
std::unique_ptr<T> m_one;
std::unique_ptr<T> m_two;
};
class C
{
public:
C(int a, int b, const std::string& c)
: m_a(a),
m_b(b),
m_c(c)
{
std::cout << "ctor a=" << m_a << ", b=" << m_b << ", c=" << m_c << "\n";
}
int m_a;
int m_b;
std::string m_c;
};
int main()
{
Test<C> t(1, 2, "3");
}
我想这是确定自C
第三构造函数参数是const std::string&
,但如何防止一类需要一个R值裁判,例如完美转发C(int, int, std::string&&)
那么m_two
将不会收到与m_one
相同的参数?
变化的测试的构造函数来
template <typename... Args>
Test(Args&... args)
不能编译。也不从m_one
和m_two
ctors中删除std::forward<Args>(args)...
。
也许最好不要在初始化'm_one'时使用'std :: forward'。 –
不能编译:main.cpp:31:error:无法绑定'std :: basic_string'左值为'std :: string && {aka std :: basic_string &&}' –
James
@James:您必须做某件事错误。沃恩的意思是[this](http://coliru.stacked-crooked.com/a/0fdc7ca0f433a18a)。经验法则是:当多次转发相同的参数时,***不要***。只需传递它,而不需要完美转发,并让目标制作副本,如果他们想要的话。如果你想转发,只能在最后一次(在这种情况下在'm_two'的初始化中)执行。 – Xeo