[英]Template : class specialization
I'm new in the C++ world.我是 C++ 世界的新手。 Sorry for my nooby question.
抱歉我的菜鸟问题。
I have a class我有一堂课
template <typename T>
class Foo
{
T t_;
void say_hello()
{ std::cout << "Ciao";}
// work with T ...
};
I want to specialize this template class for 3 types.我想将此模板类专门用于 3 种类型。
If type is ( A
or B
or C
), Then use this class如果类型是(
A
或B
或C
),则使用此类
template<>
class Foo<A or B or C>
{
void say_hello()
{ std::cout << "Hello";}
};
What's the best way to do this?做到这一点的最佳方法是什么? Thank you for your help.
感谢您的帮助。
A possible solution uses SFINAE一种可能的解决方案使用 SFINAE
template <typename T, typename = void>
class Foo
{
T t_;
void say_hello()
{ std::cout << "Ciao";}
// work with T ...
};
template <typename T>
class Foo<T, std::enable_if_t<std::is_same_v<T, A>,
|| std::is_same_v<T, B>,
|| std::is_same_v<T, C>>
{
void say_hello()
{ std::cout << "Hello";}
};
If you don't use T
inside the Foo
specialization (as in your example) you can also use a sort of self-inheritance如果您不在
Foo
专业化中使用T
(如您的示例中所示),您还可以使用一种自我继承
template <typename T>
class Foo
{
T t_;
void say_hello()
{ std::cout << "Ciao";}
// work with T ...
};
template <>
class Foo<A>
{
void say_hello()
{ std::cout << "Hello";}
};
template <>
class Foo<B> : public Foo<A>
{ };
template <>
class Foo<C> : public Foo<A>
{ };
Off Topic: if you want to use say_hello()
outside the class, is better if you make it public
(or if you declare Foo
as a struct
).题外话:如果你想在课堂外使用
say_hello()
,最好将它public
(或者如果你将Foo
声明为struct
)。
There are several possibilities, for example:有几种可能,例如:
Specialization of the method only:仅该方法的专业化:
template<>
void Foo<A>::say_hello() { std::cout << "Hello"; }
template<>
void Foo<B>::say_hello() { std::cout << "Hello"; }
template<>
void Foo<C>::say_hello() { std::cout << "Hello"; }
or, in C++17, you might do:或者,在 C++17 中,你可以这样做:
template <typename T>
class Foo
{
T t_;
void say_hello()
{
if constexpr(std::is_same_v<T, A> || std::is_same_v<T, B> || std::is_same_v<T, C>) {
std::cout << "Hello";
} else {
std::cout << "Ciao";
}
}
// work with T ...
};
Whereas regular if
works in that example, it would fail if you call code specific to A
, B
, C
.虽然常规
if
在该示例中有效,但如果您调用特定于A
、 B
、 C
代码,它将失败。 if constexpr
won't have that issue. if constexpr
不会有这个问题。
A variant of the SFINAE solution that is a bit more concise for more classes. SFINAE 解决方案的一种变体,对于更多类来说更简洁一些。
template<class T, class... Ts>
struct is_one_of;
template<class T, class Ts>
struct is_one_of<T, T, Ts...> : std::true_type {}; //maybe add std::decay_t
template<class T, class S, class Ts>
struct is_one_of<T, S, Ts...> : is_one_of<T, Ts...> {};
template<class T>
struct is_one_of<T> : std::false_type{};
template<class T, class... Ts>
constexpr bool is_one_of_v = is_one_of<T, Ts...>::value;
template <typename T, typename = void>
class Foo
{
T t_;
void say_hello()
{ std::cout << "Ciao";}
// work with T ...
};
template <typename T>
class Foo<T, std::enable_if_t<is_one_of_v<T, A, B, C>
{
void say_hello()
{ std::cout << "Hello";}
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.