使用模板参数依赖参数编写模板类的构造函数

时间:2018-05-23 16:07:52

标签: c++ templates constructor template-meta-programming

考虑以下两个类,其中构造函数接受完全不同的参数集。

class A {
public:
  A(int x, double y) {
    //do something
  }
};

class B {
public:
  B(const std::vector<bool>& x) {
    //do something
  }
};

现在,我想编写一个具有对象(可能是A或B或其他东西)的类模板TpC。换句话说,我希望能够使用以下内容:

int x;
double y;
std::vector<bool> z;
TpC<A> obj_a (x, y);
TpC<B> obj_b (z);

如何为TpC编写一个依赖于A和B构造函数参数的构造函数?写一些像特征/政策这样的东西来告诉TpC每个特定专业的参数应该是可以接受的。

3 个答案:

答案 0 :(得分:3)

您可以为TpC编写一个带有parameter pack的模板构造函数。 (正如评论建议我使用SFINAE来约束模板,否则它可能比复制构造函数更好匹配。请参阅我发布的链接中的整个代码片段。)

template <typename T, typename... U>
struct my_is_same {
    constexpr static bool value = false;
};
template <typename T1, typename T2, typename... U>
struct my_is_same<T1, T2, U...> {
    constexpr static bool value = std::is_same_v<T1, std::remove_cvref_t<T2>>;
};
template <typename T, typename... U>
inline constexpr bool my_is_same_v = my_is_same<T, U...>::value;

template <typename T>
class TpC {
    T t;
public:
    template <typename... Args, typename = std::enable_if_t<
                                             !my_is_same_v<TpC, Args...> &&
                                             std::is_constructible_v<T, Args&&...>
                                           >>
    TpC(Args&& ... args) : t(std::forward<Args>(args)...) {}
};

然后

int x;
double y;
std::vector<bool> z;
TpC<A> obj_a (x, y);
TpC<B> obj_b (z);

LIVE

答案 1 :(得分:2)

您需要使用模板构造函数。但是,为了防止调用此构造函数而不是复制构造函数,您需要添加一些消歧。例如:

template<class T>
class TpC {
     T t;
public:
     struct in_place_t { };
     static constexpr in_place_t in_place;
     template<class... ARGS>
     TpC(in_place_t, ARGS... args) : t(std::forward<ARGS>(args)...) {}
};

在C ++中,in_place中提供了std

答案 2 :(得分:-1)

如果您使用的是c ++ 11或更高版本,则可以使用变量模板构造函数和参数包扩展,在构造函数参数上调用std :: forward。类似的东西:

template <typename T>
class TpC {
    T base;
public:
    template <typename... Args>
    TpC(Args&&... args)
    : base(std::forward<Args>(args)...) {
    }
};