![](/img/trans.png)
[英]How can I elegantly write class templates that use a value implied by the template argument?
[英]How can I use templates to determine the appropriate argument passing method?
據我所知,當一個對象傳遞給一個比寄存器大的函數時,最好將它作為(const)引用傳遞,例如:
void foo(const std::string& bar)
{
...
}
這避免了必須執行可能昂貴的參數副本。
但是,當傳遞適合寄存器的類型時,將其作為(const)引用傳遞最多是冗余的,最壞的情況是:
void foo(const int& bar)
{
...
}
我的問題是,當我使用需要傳遞任何類型的模板化類時,我想知道如何充分利用這兩個世界:
template <typename T>
class Foo
{
public:
// Good for complex types, bad for small types
void bar(const T& baz);
// Good for small types, but will needlessly copy complex types
void bar2(T baz);
};
是否有模板決策方法允許我選擇正確的類型? 可以讓我做的事,
void bar(const_nocopy<T>::type baz);
根據類型選擇更好的方法?
編輯:
經過大量的定時測試后,兩個通話時間之間的差異是不同的,但非常小。 對於我的情況,解決方案可能是一個可疑的微優化。 盡管如此, TMP仍然是一項有趣的心理鍛煉。
使用Boost.CallTraits :
#include <boost/call_traits.hpp>
template <typename T>
void most_efficient( boost::call_traits<T>::param_type t ) {
// use 't'
}
如果變量復制時間很重要,那么編譯器很可能會內聯該模板的實例,而const引用的東西也同樣有效。
從技術上講,你已經給了自己一個答案。
只需為所有nocopy類型專門化no_copy<T>
模板。
template <class T> struct no_copy { typedef const T& type; };
template <> struct no_copy<int> { typedef int type; };
我能想到的唯一解決方案是使用宏為較小的類生成專用模板版本。
第一種:使用const &
- 如果要實現大到內聯,則cosnt和vs.參數不再有太大區別。
第二:這是我能想到的最好的。 無法正常工作,因為編譯器無法推斷出參數類型
template <typename T, bool UseRef>
struct ArgTypeProvider {};
template <typename T>
struct ArgTypeProvider<T, true>
{
typedef T const & ArgType;
};
template <typename T>
struct ArgTypeProvider<T, false>
{
typedef T ArgType;
};
template <typename T>
struct ArgTypeProvider2 : public ArgTypeProvider<T, (sizeof(T)>sizeof(long)) >
{
};
// ----- example function
template <typename T>
void Foo(typename ArgTypeProvider2<T>::ArgType arg)
{
cout << arg;
}
// ----- use
std::string s="fdsfsfsd";
// doesn't work :-(
// Foo(7);
// Foo(s);
// works :-)
Foo<int>(7);
Foo<std::string>(s);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.