【问题标题】:Conditional Compile using Boost type-traits使用 Boost 类型特征进行条件编译
【发布时间】:2010-07-29 20:49:24
【问题描述】:

我有一个模板,我想根据参数的类型有条件地编译它。我只关心区分“普通旧数据”(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
}}

我一直在查看 boost 库,我可以看到它们似乎拥有我想要的东西。但是,我不明白 #if 语句的正确语法是什么。

任何帮助将不胜感激。


编辑 --- 阅读回复后,我发现我在对问题的定义中忽略了一些内容。类foo 是一个模板类,它只需要实例化与class type T 正确的bar 版本。我一直在寻找可以解决编译时间的解决方案。希望这能解决我的问题。

【问题讨论】:

    标签: c++ boost


    【解决方案1】:

    您可以在没有 enable_if 的情况下执行此操作,因为您所需要的只是根据类型特征进行调度。 enable_if 用于在重载解析中添加/删除模板实例化。您可能希望使用调用特征来选择将对象传递给您的函数的最佳方法。通常,对象应该通过引用传递,而 POD 是通过值传递。 call_traits 让您在 constnon-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
        }
    };
    

    【讨论】:

      【解决方案2】:

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

      假设IsPod&lt;T&gt;::result 返回类似Boolean&lt;true&gt;/Boolean&lt;false&gt;

      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());
          }
      }
      

      【讨论】:

        【解决方案3】:

        在这里使用预处理器是不可能的。改为查看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
        }
        

        【讨论】:

        • 这将是一个编译错误,一旦类模板被实例化,T 是固定的,此时当你尝试调用bar 时它会看到两个定义并且它会失败编译其中之一。请注意,这不是 SFINAE,因为它不会是替换失败——类型在成员实例化之前是固定的(或者我认为,我永远不确定这些事情 :))。
        猜你喜欢
        • 2012-11-27
        • 2012-10-02
        • 1970-01-01
        • 1970-01-01
        • 2019-01-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多