gpt4 book ai didi

c++ - C++ 中的自动评估策略选择

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:00:23 26 4
gpt4 key购买 nike

考虑以下函数模板:

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

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

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


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

#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))

虽然这只是一个准可移植 hack。

如您所见,我的一般方法并不是对所有情况都令人满意。


作为业余程序员,我既没有实际经验,也无法访问生产质量代码以供引用。我也意识到这可能看起来像是过早优化的糟糕案例,但我真的对以下几件事很感兴趣:

  1. 您过去使用过这种优化*吗?
  2. Boost(或任何其他公共(public))库是否已提供类似功能?
  3. 如果对 #1 或 #2 的回答是"is"——如何处理非类模板案例?
  4. 是否有任何明显的陷阱是我没有看到的类似的东西?
  5. 最后,这样做是否明智?

* 未介绍。 ;)

最佳答案

  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. 当然可以!

关于c++ - C++ 中的自动评估策略选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3191854/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com