2010-07-29 47 views
7

我有一个模板,我想根据参数的类型进行有条件编译。我只关心区分“普通旧数据”(POD),即整数等或类/结构。我在Windows上使用C++ VS2008。使用Boost类型特征的条件编译

template<T> 
class foo 
{ 
    void bar(T do_something){ 
    #if IS_POD<T> 
     do something for simple types 
    #else 
     do something for classes/structs 
    #endif 
}} 

我一直在寻找增强库,我可以看到他们似乎有我想要的。但是,我不明白#if声明的正确语法是什么。

任何帮助,将不胜感激。


编辑--- 阅读的答复后,我看到了我在这个问题的定义忽略了什么。类foo是一个模板类,只需要将bar的版本实例化为class type T即可。我正在寻找可以在编译时解决的解决方案。希望这清除了我的问题。

回答

7

你可以不用enable_if,因为所有你需要的是根据类型特征派遣。 enable_if用于向/从重载解析添加/删除模板实例。您可能希望使用呼叫特征来选择将对象传递给函数的最佳方法。通常,对象应该按引用传递,而POD按值传递。 call_traits让我们选择const非const参考。以下代码使用const参考。

#include <boost/type_traits.hpp> 
#include <boost/call_traits.hpp> 

template <typename T> 
class foo { 
public: 
    void bar(typename boost::call_traits<T>::param_type obj) { 
     do_something(obj, boost::is_pod<T>()); 
    } 
private: 
    void do_something(T obj, const boost::true_type&) 
    { 
     // do something for POD 
    } 
    void do_something(const T& obj, const boost::false_type&) 
    { 
     // do something for classes 
    } 
}; 
0

这里使用预处理器是不可能的。改为看看Boost Enable If library

具体来说,在你的情况下,它看起来像(未测试):

void bar (typename enable_if <is_pod <T>, T>::type do_something) 
{ 
    // if is POD 
} 

void bar (typename disable_if <is_pod <T>, T>::type do_something) 
{ 
    // if not 
} 
+0

这将是一个编译错误,一旦类模板实例,'T'是固定的,在这一点上,当您尝试调用'bar'会看到两个定义,它将无法编译其中之一。请注意,这不是SFINAE,因为它不会是替代失败 - 类型在成员的实例化之前是固定的(或者我认为,我不确定这些东西:))。 – 2010-07-29 23:28:19

3

不能与预处理解决这个问题,因为它不知道C++。 (这是一个愚蠢的文本替换工具。)使用模板来做到这一点。

假设IsPod<T>::result回报的东西都Boolean<true>/Boolean<false>

template<T> 
class foo 
{ 
    void do_something(T obj, Boolean<true> /*is_pod*/) 
    { 
     // do something for simple types 
    } 
    void do_something(T obj, Boolean<false> /*is_pod*/) 
    { 
     // do something for classes/structs 
    } 

    void bar(T obj) 
    { 
     do_something(obj, IsPod<T>::result()); 
    } 
}