Fre*_*red 5 c++ templates sfinae
在阅读了这个问题的答案之后,我了解到SFINAE可以用来根据类是否具有某个成员函数来选择两个函数.它等同于以下内容,只是将if语句中的每个分支拆分为重载函数:
template<typename T>
void Func(T& arg)
{
if(HAS_MEMBER_FUNCTION_X(T))
arg.X();
else
//Do something else because T doesn't have X()
}
Run Code Online (Sandbox Code Playgroud)
变
template<typename T>
void Func(T &arg, int_to_type<true>); //T has X()
template<typename T>
void Func(T &arg, int_to_type<false>); //T does not have X()
Run Code Online (Sandbox Code Playgroud)
我想知道是否有可能扩展SFINAE来做多个规则.一些与此相当的东西:
template<typename T>
void Func(T& arg)
{
if(HAS_MEMBER_FUNCTION_X(T)) //See if T has a member function X
arg.X();
else if(POINTER_DERIVED_FROM_CLASS_A(T)) //See if T is a pointer to a class derived from class A
arg->A_Function();
else if(DERIVED_FROM_CLASS_B(T)) //See if T derives from class B
arg.B_Function();
else if(IS_TEMPLATE_CLASS_C(T)) //See if T is class C<U> where U could be anything
arg.C_Function();
else if(IS_POD(T)) //See if T is a POD type
//Do something with a POD type
else
//Do something else because none of the above rules apply
}
Run Code Online (Sandbox Code Playgroud)
这样的事情可能吗?
谢谢.
这当然是可能的; 你必须要小心确保所有分支都是互斥的,否则你最终会产生歧义.
看看Boost Type Traits和Boost Enable If,它们是支持此功能的两个最佳工具. Boost ICE(代表Integral Constant Expression)可用于组合多种类型特征,以帮助您进行更复杂的类型匹配(并确保您的重载是互斥的.
这可能有点复杂和复杂,所以这是一个相对简单的例子.假设您有一个类层次结构:
struct Base { };
struct Derived : Base { };
Run Code Online (Sandbox Code Playgroud)
你想调用一个函数的一个超负荷foo的Base,而另一个重载从派生的任何类Base.第一次尝试可能如下:
#include <boost/type_traits.hpp>
#include <boost/utility/enable_if.hpp>
using namespace boost;
using namespace boost::type_traits;
template <typename T>
typename enable_if<is_same<Base, T>, void>::type
foo(const T&) { }
template <typename T>
typename enable_if<is_base_of<Base, T>, void>::type
foo(const T&) { }
Run Code Online (Sandbox Code Playgroud)
但是,is_base_of如果T是基类,则返回true ,因此如果您尝试调用foo(Base()),则存在歧义,因为两个函数模板都匹配.我们可以通过结合使用类型特征和使用Boost ICE帮助程序来解决这个问题:
template <typename T>
typename enable_if<is_same<Base, T>, void>::type
foo(const T&) { }
template <typename T>
typename enable_if<
ice_and<
is_base_of<Base, T>::value,
ice_not<is_same<Base, T>::value>::value
>, void>::type
foo(const T&) { }
Run Code Online (Sandbox Code Playgroud)
这些重载是互斥的,它们确保没有歧义.
你的一些例子不受支持(即,HAS_MEMBER_FUNCTION_X我不确定IS_TEMPLATE_CLASS_C- 根据你想用它做什么,你可能能够做些工作),但总的来说这是可能的.
| 归档时间: |
|
| 查看次数: |
2453 次 |
| 最近记录: |