我有一个类模板,我想介绍几个模板特化。那些模板特化与某些现有类型相同。从概念上讲,我想将它们实现为别名/ 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;
上述在C ++(或C ++ 11)中是否可能以某种方式存在?如果我没有必要将Common<...>
实现为继承TypeZ
的类,那将会很棒 - 实际代码比上面显示的更复杂并且继承TypeZ
不是很好那里的想法。
答案 0 :(得分: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;
然后您使用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; };
然后您不需要使用嵌套类型别名。
答案 1 :(得分:4)
是的,您可以使用type aliases:
template<typename T> using Common = TypeZ;
请参阅链接以获取更多可能的示例。 using
可以在任何可以使用typedef
的地方使用,也可以在上面的模板别名中使用,因此我建议您在编写C ++ 11的任何地方使用using
而不是typedef
。< / p>
如果您需要更复杂的映射,可以使用std::enable_if
或std::conditional
与std::is_same
结合使用一些简单的模板元编程。
例如,如果您只需要专门针对3种类型,请使用this:
#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>(), "");
两个实现都等同于一个名称,并且您必须使用函数调用运算符()
或::value
中的成员访问者std::conditional
。
答案 2 :(得分:0)
我不确定关于这个问题的代码在 C++ 标准中是否允许。
在我看来,'using' 将创建一个新的数据类型,请参阅下面的示例代码。
using TypeZ::TypeZ;
继承构造函数。
#include <iostream>
template<typename T>
class Base { using type_universal = T; };
//e.g. Normal template specialization
template<> class Base<int> { using type_int = int; };
//Target:
class TypeZ {public: int I_am_typeZ = 1; };
//Alias:
template<> class Base<double> : public TypeZ { using TypeZ::TypeZ; };
int main() {
Base<double> instance;
std::cout<<"Base<double>.I_am_typeZ = "<<instance.I_am_typeZ<<std::endl;
return 0;
}