是否可以将实现模板专门化定义为另一种类型的typedef?

p12*_*p12 10 c++ templates typedef c++11

我有一个类模板,我想介绍几个模板特化.那些模板特化与某些现有类型相同.从概念上讲,我想将它们实现为别名/ typedef.

以下示例代码应显示我想要执行的操作:

template<class T> class Common {
    /// general implementation
};

class TypeZ;    

template<> class Common<Type1> = TypeZ; // <<< how to do this?
template<> class Common<Type2> = TypeZ;
template<> class Common<Type3> = TypeZ;
Run Code Online (Sandbox Code Playgroud)

在C++(或C++ 11)中,上述内容是否可行?如果我不必实现Common<...>作为继承的类TypeZ- 那将是很好的- 实际代码比上面显示的更复杂,并且继承TypeZ在那里不是一个好主意.

Sim*_*ple 10

假设只有某些特殊化的Common别名,TypeZ你可以这样做:

template<class T> class Common {
    struct type {
        /// general implementation
    };
};

template<> class Common<Type1> { using type = TypeZ; };
template<> class Common<Type2> { using type = TypeZ; };
template<> class Common<Type3> { using type = TypeZ; };

template<class T> using common_t = typename Common<T>::type;
Run Code Online (Sandbox Code Playgroud)

然后你使用common_t<T>而不是Common<T>.

只是为了接受继承的想法,你试过这个吗?

template<> class Common<Type1> : public TypeZ { using TypeZ::TypeZ; };
template<> class Common<Type2> : public TypeZ { using TypeZ::TypeZ; };
template<> class Common<Type3> : public TypeZ { using TypeZ::TypeZ; };
Run Code Online (Sandbox Code Playgroud)

然后,您不需要使用嵌套类型别名.

  • 我甚至不确定我是否完全理解这一点,但是+1会让我的大脑在新的不舒服的方向上伸展. (2认同)

rub*_*nvb 5

是的,您可以使用类型别名

template<typename T> using Common = TypeZ;
Run Code Online (Sandbox Code Playgroud)

请参阅链接以获取更多可能的示例。using可以在任何typedef可以使用的地方使用,以及上面的模板别名,因此我建议usingtypedef编写C ++ 11的任何地方使用。


如果您需要更复杂的映射,则可以使用std::enable_ifstd::conditional与结合使用一些简单的模板元编程std::is_same。例如,如果您只需要专门研究3种类型,请使用以下方法

#include <type_traits>

class Type1 {};
class Type2 {};
class Type3 {};
class Type4 {};

class TypeZ {};

// Implementation 1
template<typename T>
constexpr bool is_Type123_func()
{
  return std::is_same<T, Type1>() || std::is_same<T, Type2>() || std::is_same<T, Type3>();
}
template<typename T>
using Common_byfunc = typename std::conditional<is_Type123_func<T>(), TypeZ, T>::type;

static_assert(std::is_same<Common_byfunc<Type1>, TypeZ>(), "");
static_assert(std::is_same<Common_byfunc<Type2>, TypeZ>(), "");
static_assert(std::is_same<Common_byfunc<Type3>, TypeZ>(), "");
static_assert(!std::is_same<Common_byfunc<Type4>, TypeZ>(), "");

// Implementation 2
template<typename T>
struct is_Type123 : public std::conditional<std::is_same<T, Type1>() || std::is_same<T, Type2>() || std::is_same<T, Type3>(), std::true_type, std::false_type>::type {};
template<typename T>
using Common = typename std::conditional<is_Type123<T>::value, TypeZ, T>::type;

static_assert(std::is_same<Common<Type1>, TypeZ>(), "");
static_assert(std::is_same<Common<Type2>, TypeZ>(), "");
static_assert(std::is_same<Common<Type3>, TypeZ>(), "");
static_assert(!std::is_same<Common<Type4>, TypeZ>(), "");
Run Code Online (Sandbox Code Playgroud)

这两种实现是等价高达名字,你必须使用一个函数调用操作的事实()或成员访问::valuestd::conditional

  • @zymzam:它将与辅助特性一起使用,请参见更新。 (2认同)