使用Boost类型特征进行条件编译

时间:2010-07-29 20:49:25

标签: c++ boost

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

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的{​​{1}}版本。我一直在寻找一个可以在编译时解决的解决方案。希望这能解决我的问题。

3 个答案:

答案 0 :(得分: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
    }
};

答案 1 :(得分: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());
    }
}

答案 2 :(得分: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
}