Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

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...)?

like image 971
fuji Avatar asked Jun 23 '26 04:06

fuji


1 Answers

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:

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. Maybe it's is_fundamental as other answers proposed.

And then just use it:

template<class T>
class Val {
public:
    Val() = default;
    Val(param_type<T> v) : _v(v) { }
};
like image 58
Barry Avatar answered Jun 24 '26 19:06

Barry