[英]Template method specialization for multiple types
我有一個類“A”,它暴露了模板方法foo。 Foo有一個標准的實現,它適用於B,C。 它還有一個特殊的D實現。
class A
{
template<typename T>
void foo()
{
//standard implementation
}
template<>
void foo<D>
{
//special implementation
}
}
class B{};
class C{};
class D{};
int main()
{
A<B> a1;
A<C> a2;
A<D> a3;
}
現在,我需要添加類E,這需要“foo”與D相同的特殊實現。有沒有辦法說出類似的內容:對於所有類型都使用標准foo。 對於D,E(等等)的特殊實現。
class A
{
template<typename T>
void foo()
{
//standard implementation
}
template<>
void foo<D && E> <-- PseudoCode - It doesn't work
{
//special implementation
}
}
class B{};
class C{};
class D{};
class E{};
int main()
{
A<B> a1;
A<C> a2;
A<D> a3;
A<E> a4;
}
我在考慮使用特質課程。 但我希望有更簡單的方法來實現這一目標。 謝謝
使用Walter Brown的(C ++ 1z) void_t
。
#include <iostream>
#include <type_traits>
template <typename...>
using void_t = void;
template <typename T, typename = void>
struct has_bar
: std::false_type { };
template <typename T>
struct has_bar<T, void_t<decltype( std::declval<T&>().bar() ) > >
: std::true_type { };
class A {
public:
void foo() { };
};
class B {
public:
void bar() { };
};
class C {
public:
void bar() { };
};
template <typename T>
typename std::enable_if<!has_bar<T>::value, void>::type
fun(T t) {
std::cout << "fun" << std::endl;
}
template <typename T>
typename std::enable_if<has_bar<T>::value, void>::type
fun(T t) {
std::cout << "special fun" << std::endl;
}
代碼...
int main(const int argc, const char* argv[argc]) {
A a;
B b;
C c;
fun(a);
fun(b);
fun(c);
return 0;
}
打印出來
fun
special fun
special fun
注意,這不會檢查任何類型的語義,因此可能更好地將bar()
聲明為接口並使用std::is_base_of
。
你應該看看SFINAE在編譯時啟用和禁用功能
如果D和E是特殊的,他們讓我們說成員void bar()
而不是其他人,你可以實際實現你自己的類型特征:
template<typename T>
struct has_bar {
private:
template<typename C> static std::true_type test(decltype(&C::bar)*);
template<typename C> static std::false_type test(...);
public:
constexpr static bool value = decltype(test<T>(nullptr))::value;
};
/* false */ /* true */
cout << boolalpha << has_bar<A> << " " << has_bar<E> << endl;
現在使用此類型特征,您可以使用std :: enable_if作為編譯時間開關:
/* standard if no bar */
template<typename T, typename = enable_if_t< !has_bar<T> >>
void foo()
{
//standard implementation
}
/* special if bar */
template<<typename T, typename = enable_if_t< has_bar<T> >>
void foo()
{
//special implementation
}
如果沒有定義一些SFINAE機器,AFAIK就無法做到這一點。 現在我能想到的最小值不包括type_traits
標題將是以下內容:
定義“自制” enable_if
和is_same
類型特征如下。
namespace mine {
template<bool, typename T = void> struct enable_if {};
template<typename T> struct enable_if<true, T> { typedef T type; };
template<typename T, typename U> struct is_same { static bool const value = false; };
template<typename T> struct is_same<T, T> { static bool const value = true; };
};
在class A
成員函數foo()
中應用SFINAE,如下所示:
class A {
template<typename T>
struct pred {
static bool const value = mine::is_same<T, B>::value ||
mine::is_same<T, C>::value || mine::is_same<T, D>::value || mine::is_same<T, E>::value;
};
public:
template<typename T>
typename mine::enable_if< pred<T>::value, void>::type
foo() { std::cout << "special implementation" << std::endl; }
template<typename T>
typename mine::enable_if<!pred<T>::value, void>::type
foo() {std::cout << "standard implementation" << std::endl; }
};
PS的好處是上述解決方案也適用於C ++ 11之前的編譯器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.