可变模板和完美转发到特定模板 class
Variadic templates and perfect forwarding to specific template class
我想在我的 "myArgs class" 中实现一个完美的转发构造函数,
这应该只涉及 myClassBase<>
的专业化。
粗略地说:为 myClassBase<>
的每个变体调用此构造函数
但它不会编译:'<function-style-cast>' : cannot convert from 'myClass' to 'myArgs'.
我认为这是因为编译器无法从 Args&&
推导出 myClassBase<T, D>
。
查看这个(非常基本的)示例:
template <class T, class D>
class myClassBase
{
private:
T data;
D data2;
};
typedef myClassBase<char, int> myClass;
class myArgs
{
public:
myClass m_data;
template <class T, class D>
myArgs(myClassBase<T, D>&& rhs) :
m_data(std::forward< myClassBase<T, D> >(rhs))
{
}
};
template <class... Args>
void var_args(Args&&... args)
{
myArgs( std::forward<Args>(args)... );
}
测试内容:
myClass x;
var_args(x);
如果我将 var_args 函数参数从 void var_args(Args&&... args)
更改为 void var_args(Args... args)
它会起作用。
顺便说一句。在我的真实代码中,myClass 当然支持移动语义。
提前致谢。
克里斯蒂安.
template <class T, class D>
myArgs(myClassBase<T, D>&& rhs) :
m_data(std::forward< myClassBase<T, D> >(rhs))
{
}
rhs
有右值引用,不是转发引用。函数参数中的转发引用采用 T&&
形式,其中 T
是一些推导的模板参数。您可以通过推导 T
而不是指定 myClassBase
.
来解决此问题
template <class T>
myArgs(T&& rhs) :
m_data(std::forward<T>(rhs))
{
}
如果你想让这个函数只在T
是一个myClassBase
时有效,你可以写一个特征来检查它:
template <typename T>
struct isMyClassBaseImpl : std::false_type{};
template <typename T, typename D>
struct isMyClassBaseImpl<myClassBase<T,D>> : std::true_type{};
template <typename T>
using isMyClassBase = isMyClassBaseImpl<std::decay_t<T>>;
那你就可以SFINAE出来了:
template <class T, std::enable_if_t<isMyClassBase<T>::value>* = nullptr>
myArgs(T&& rhs) :
m_data(std::forward<T>(rhs))
{
}
我想在我的 "myArgs class" 中实现一个完美的转发构造函数,
这应该只涉及 myClassBase<>
的专业化。
粗略地说:为 myClassBase<>
但它不会编译:'<function-style-cast>' : cannot convert from 'myClass' to 'myArgs'.
我认为这是因为编译器无法从 Args&&
推导出 myClassBase<T, D>
。
查看这个(非常基本的)示例:
template <class T, class D>
class myClassBase
{
private:
T data;
D data2;
};
typedef myClassBase<char, int> myClass;
class myArgs
{
public:
myClass m_data;
template <class T, class D>
myArgs(myClassBase<T, D>&& rhs) :
m_data(std::forward< myClassBase<T, D> >(rhs))
{
}
};
template <class... Args>
void var_args(Args&&... args)
{
myArgs( std::forward<Args>(args)... );
}
测试内容:
myClass x;
var_args(x);
如果我将 var_args 函数参数从 void var_args(Args&&... args)
更改为 void var_args(Args... args)
它会起作用。
顺便说一句。在我的真实代码中,myClass 当然支持移动语义。
提前致谢。 克里斯蒂安.
template <class T, class D>
myArgs(myClassBase<T, D>&& rhs) :
m_data(std::forward< myClassBase<T, D> >(rhs))
{
}
rhs
有右值引用,不是转发引用。函数参数中的转发引用采用 T&&
形式,其中 T
是一些推导的模板参数。您可以通过推导 T
而不是指定 myClassBase
.
template <class T>
myArgs(T&& rhs) :
m_data(std::forward<T>(rhs))
{
}
如果你想让这个函数只在T
是一个myClassBase
时有效,你可以写一个特征来检查它:
template <typename T>
struct isMyClassBaseImpl : std::false_type{};
template <typename T, typename D>
struct isMyClassBaseImpl<myClassBase<T,D>> : std::true_type{};
template <typename T>
using isMyClassBase = isMyClassBaseImpl<std::decay_t<T>>;
那你就可以SFINAE出来了:
template <class T, std::enable_if_t<isMyClassBase<T>::value>* = nullptr>
myArgs(T&& rhs) :
m_data(std::forward<T>(rhs))
{
}