考虑下面的函数模板:++自动评估战略选择用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))
虽然这仅仅是一个准便携式黑客。
正如你所看到的,我的一般方法并不是真的令人满意。
作为一个业余爱好者的程序员,我也没有现实世界的经验,也没有得到获得生产质量的代码以供参考。我也意识到这可能看起来像是一个不成熟的优化案例,但我真的对以下几件事情感兴趣:
- 您或者您是否曾经使用过这种类型的优化?
Boost
(或任何其他公共)库是否已提供类似的功能?- 如果#1或#2的答案是'是' - 那么如何处理非类模板案例?
- 是否有任何明显的缺陷,我没有看到这样的事情?
- 最后,这是一个理智的事情吗?
*未分析。 ;)
会提及http://www.boost.org/doc/libs/1_43_0/doc/html/ref.html – 5ound 2010-07-07 04:25:57
@ 5ound:也有用,谢谢! – chrosph 2010-07-07 04:30:45