合并const和非const std :: list的模板特化

时间:2017-06-15 15:46:41

标签: c++ templates c++14 template-specialization

是否有一种简单的方法可以将两个模板专业化合并为一个,可能使用std::enable_if,用于以下MWE?

#include <string>
#include <list>
#include <memory>

class A {
    // ...
};
class B {
    // ...
};

template<typename T> class C {};

template<typename T>
class C<std::list<T> &> : public A, public B
{
    std::list<T> &l_ref;
public:
    C(std::list<T> &lr) : l_ref{lr} { }
    // ...
};

template<typename T>
class C<const std::list<T> &> : public A, public B
{
    const std::list<T> &l_ref;
public:
    C(const std::list<T> &lr) : l_ref{lr} { }
    // ...
};

对于惯用语

template<typename T>
struct C<T, typename std::enable_if<
    std::is_same<T, std::list<E> &>::value ||
    std::is_same<T, const std::list<E> &>::value>::type>
    : public A, public B
{
    // ...

方式,我认为没有办法让E可以推断或指定&#34;任何std::list&#34;的类型。

2 个答案:

答案 0 :(得分:1)

您可以创建特征,首先使用SFINAE,例如:

template <typename T> struct is_a_stdlist_ref : std::false_type {};
template <typename ... Ts>
struct is_a_stdlist_ref<std::list<Ts...>&> : std::true_type {};
template <typename ... Ts>
struct is_a_stdlist_ref<const std::list<Ts...>&> : std::true_type {};

template<typename T, typename Enabler = void> struct C;

template<typename T>
struct C<T, std::enable_if_t<is_a_stdlist_ref<T>::value>>
    : public A, public B
{
    //...
};

答案 1 :(得分:0)

  

是否有一种简单的方法可以将两个模板特化合并为一个,也许使用std :: enable_if,用于以下MWE?

您是否接受没有std::enable_it的解决方案?

为了使解决方案更加灵活,我建议定义一个类型特征specIndex来修复类型相关索引,其中0是&#34;泛型类型&#34;,{{ 1}}是&#34; std :: list&amp; 1 const`,其他整数可以引用其他专业

or

下一步是为template <typename> struct specIndex { static constexpr std::size_t value { 0U }; }; // generic version template <typename T> struct specIndex<std::list<T> &> { static constexpr std::size_t value { 1U }; }; // pro lists template <typename T> struct specIndex<std::list<T> const &> { static constexpr std::size_t value { 1U }; }; // pro lists

添加默认模板整数参数
C

最后一步是定义索引1(template <typename T, std::size_t = specIndex<T>::value> class C { }; 或常量)专门化

std::list<T> &

以下是一个完整的例子

template<typename T>
class C<T, 1U> : public A, public B
 {
   private:
      T & l_ref;

   public:
      C (T & lr) : l_ref{lr}
       { std::cout << "- list version" << std::endl; }
 };
相关问题