【问题标题】:Automatic Evaluation Strategy Selection in C++C++ 中的自动评估策略选择
【发布时间】:2011-03-12 15:14:23
【问题描述】:

考虑以下函数模板:

template<typename T> void Foo(T)
{
  // ...
}

如果T 恰好是一个整数类型,或者至少是一个复制成本低的类型,则按值传递语义是有意义的。 另一方面,如果 T 恰好是一种昂贵的复制类型,则使用 pass-by-[const]-reference 语义更有意义。

让我们假设您正在编写一个库。理想情况下,作为库的实现者,您的工作是为您的消费者提供尽可能通用和高效的干净 API。那么,您如何提供一个通用接口来满足这两种类型的参数传递策略?


这是我第一次尝试让它工作:

#include <boost/type_traits.hpp>

template<typename T> struct DefaultCondition
{
  enum {value = boost::is_integral<T>::value /* && <other trait(s)> */};
};

template< typename T, class Condition = DefaultCondition<T> > class Select
{
  template<bool PassByValue = Condition::value, class Dummy = void> struct Resolve
  {
    typedef T type;
  };

  template<class Dummy> struct Resolve<false, Dummy>
  {
    typedef const T& type;
  };

  public: typedef typename Resolve<>::type type;
};

典型用法:

template<typename T> class EnterpriseyObject
{
  typedef typename Select<T>::type type;

  public: explicit EnterpriseyObject(type)
  {
    // ...
  }
};

struct CustomType {};

void Usage()
{
  EnterpriseyObject<int>(0); // Pass-by-value.
  (EnterpriseyObject<CustomType>(CustomType())); // Pass-by-const-reference.
}

这当然会间接破坏非类模板的隐式模板参数推导:

template<typename T> void Foo(typename Select<T>::type)
{
  // ...
}

void Usage()
{
  Foo(0);      // Incomplete.
  Foo<int>(0); // Fine.
}

这可以通过Boost.Typeof 库和一个宏来“修复”,例如WinAPI

#define Foo(Arg) ::Foo<BOOST_TYPEOF((Arg))>((Arg))

虽然这只是一个准便携式黑客。

如您所见,我的一般方法并不适用于所有情况。


作为一名业余程序员,我既没有实际经验,也无法获得生产质量的代码以供参考。我也意识到这似乎是过早优化的一个糟糕案例,但我真的对以下几件事感兴趣:

  1. 您过去是否或曾经使用过此类优化*?
  2. Boost(或任何其他公共)库是否已提供类似功能?
  3. 如果 #1 或 #2 的答案是“是”-- 非类模板情况如何处理?
  4. 这样的事情有什么我没有看到的明显缺陷吗?
  5. 最后,这是一件理智的事情吗?

* 未分析。 ;)

【问题讨论】:

标签: c++ templates pass-by-reference parameter-passing pass-by-value


【解决方案1】:
  1. 是的。每时每刻。我自己用。
  2. 是的,使用Boost.Utility's Call Traits :)

    用法是……

    template <typename T>
    void foo(boost::call_traits<T>::param_type param)
    {
        // Use param
    }
    
  3. 据我所知,非类模板是按值传递的,除非这样做更快。由于部分模板专业化,因此可以相对轻松地进行自定义。

  4. 抱歉,并没有真正阅读您所做的事情,它看起来就像我几个月前经历的一样。因此,无法真正回答这个问题。我的建议是通读 Boost.Utility。

  5. 当然!

【讨论】:

  • 优秀。发帖前应该仔细看看。非常感谢! ;)
猜你喜欢
  • 1970-01-01
  • 2022-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-25
  • 2021-10-30
  • 2022-01-21
相关资源
最近更新 更多