2

考虑下面的函数模板:++自动评估战略选择用C

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

传递值语义意义,如果T正好是整数类型,或至少一种类型的便宜复制。 另一方面,如果T碰巧是复制的昂贵类型,则使用pass-by- [const]引用语义更有意义。

让我们假设你正在写一个图书馆。理想情况下,作为一名图书馆实施者,您的工作就是为您的消费者提供一个既简洁又高效的干净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. 最后,这是一个理智的事情吗?

*未分析。 ;)

+1

会提及http://www.boost.org/doc/libs/1_43_0/doc/html/ref.html – 5ound 2010-07-07 04:25:57

+0

@ 5ound:也有用,谢谢! – chrosph 2010-07-07 04:30:45

回答

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

+0

优秀。张贴之前应该看起来更难。非常感谢! ;) – chrosph 2010-07-07 04:18:35