Jam*_*mes 4 c++ templates perfect-forwarding c++11
以下是安全的吗?第一类成员初始化后不会std::string被发现move吗?打印出来好,但我不确定.
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");
}
Run Code Online (Sandbox Code Playgroud)
我想这是好的,因为第三个ctor参数C是const std::string&,但是如何防止在一个采用r值ref的类中进行完美转发,例如,C(int, int, std::string&&)因为那时m_two不会收到相同的ctor args m_one?
将测试的ctor更改为
template <typename... Args>
Test(Args&... args)
Run Code Online (Sandbox Code Playgroud)
不编译.也没有删除std::forward<Args>(args)...来自m_one和m_twoctors.
你会想要使用这样的东西:
#include <memory>
#include <string>
#include <iostream>
#include <utility>
template <typename T>
class Test
{
public:
template <typename... Args>
Test(Args&&... args)
: m_one(new T(args...)), // avoid moving the first time
m_two(new T(std::forward<Args>(args)...)) // but allowing moving the last time
{
}
private:
std::unique_ptr<T> m_one;
std::unique_ptr<T> m_two;
};
class C
{
public:
C(int a, int b, std::string c) // rule of thumb -- if you are going to copy an argument
// anyway, pass it by value.
: m_a(a),
m_b(b),
m_c(std::move(c)) // you can safely move here since it is the last use.
{
std::cout << "ctor a=" << m_a << ", b=" << m_b << ", c=" << m_c << "\n";
}
int m_a;
int m_b;
std::string m_c;
};
Run Code Online (Sandbox Code Playgroud)
因为m_one,参数使用左值引用,因此不会发生移动.因为m_two,std::forward将使用适当的右值引用.以该std::string参数C的值,并使用std::move使其成为任何一种情况下正常工作.如果传递左值引用,则参数将被复制构造,但是如果传递右值引用,则参数将被移动构造.在任何一种情况下,您都可以将参数移动到您的m_c成员中以提高效率.
| 归档时间: |
|
| 查看次数: |
377 次 |
| 最近记录: |