[英]c++ template class pass constructor by ref depending on type
Let's say I have a class which looks like this which should either be constructed by value if T
is a simple type like double
or by reference if T
is more complex. 假设我有一个看起来像这样的类,如果
T
是一个像double
这样的简单类型,或者如果T
更复杂,那么它应该由值构造。
The code I have so far looks like this: 到目前为止我的代码看起来像这样:
template<class T>
class Val {
public:
Val() = default;
Val(double v) : _v(v) {}
template<typename U = T>
Val(const &T v,
typename std::enable_if<!std::is_same<U,double>::value, bool>::type = 0)
: _v(v) {}
private:
T _v;
};
Which works, but feels really sketchy, since an additional parameter is introduced into the constructor. 哪个有效,但感觉非常粗略,因为在构造函数中引入了一个额外的参数。 Is there a better solution to this problem?
这个问题有更好的解决方案吗? It seems like this would be better suited for an overload or template specialization solution?
这似乎更适合过载或模板专业化解决方案? Can this be solved generally for all simple types (
int
, float
, double
...)? 对于所有简单类型(
int
, float
, double
......),这通常可以解决吗?
You only need to have one constructor. 您只需要一个构造函数。 It, after all, does the same thing in both cases right?
毕竟,它在两种情况下做同样的事情对吗? First, define a type trait which, based on
T
, is either a value or reference: 首先,定义一个基于
T
的类型特征,它是值或引用:
template <typename T>
using param_type = std::conditional_t<
is_complex_type<T>::value,
T const&,
T>;
Where is_complex_type
is some appropriate type trait to be determined later. 其中
is_complex_type
是稍后要确定的某种适当的类型特征。 Maybe it's is_fundamental
as other answers proposed. 也许这是
is_fundamental
其他答案建议。
And then just use it: 然后使用它:
template<class T>
class Val {
public:
Val() = default;
Val(param_type<T> v) : _v(v) { }
};
There is std::is_fundamental
which should fit you. 有
std::is_fundamental
应该适合你。 Best looking solution for me is: 对我来说最好看的解决方案是:
template<class T>
typename std::enable_if< std::is_fundamental<T>::value >::type func(T p_arg){}
template<class T>
typename std::enable_if< !std::is_fundamental<T>::value >::type func(T const &p_arg){}
Just a little modified version of your code along with CyberGuy's recommendation of std::is_fundamental
will do what you want. 只需对代码进行一些修改后的版本以及CyberGuy对
std::is_fundamental
的推荐std::is_fundamental
。
#include <iostream>
using namespace std;
template <class T>
class Val
{
public:
template <typename U = T>
Val(T v,
typename std::enable_if<std::is_fundamental<U>::value>::type* = 0)
: _v(v)
{
cout << "fundamental" << endl;
}
template <typename U = T>
Val(T const& v,
typename std::enable_if<!std::is_fundamental<U>::value>::type* = 0)
: _v(v)
{
cout << "complex" << endl;
}
private:
T _v;
};
struct A {};
int main()
{
Val<double> v1(1);
Val<char> v2('a');
Val<A> v3(A{});
}
Output: 输出:
fundamental
fundamental
complex
You may use boost::call_traits<T>::param_type
您可以使用
boost::call_traits<T>::param_type
template<class T>
class Val {
public:
Val() = default;
Val(boost::call_traits<T>::param_type v) : _v(v) {}
private:
T _v;
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.