模板功能
回答
他們檢查你即將到來的C++標準的意識。新的功能被稱爲「可變參數模板」,看起來像這樣:
template<typename... Args> void f(const Args&... args)
{
// do something
}
對於更復雜的例子看,如this tutorial。
這不是說所有的參數都是相同的類型嗎? – 2011-05-21 08:51:52
@George:不。 – ybungalobill 2011-05-21 08:52:32
參數列表也可以是「Args && ...」,用於完美轉發。 – Philipp 2011-05-21 09:01:41
我同意,他們是最有可能尋找可變參數模板,但對於它的緣故,可以採取在C++ 03不同的方法:
使用變體類型
使用變體類型的容器。在這種情況下boost::variant
是行不通的,因爲它限制類型的數量,但可以使用boost::any
:
void foo(std::vector<boost::any> args);
相比可變參數模板,用戶代碼會更加麻煩,作爲代替書面方式foo(a, b, c, d)
,他們會必須手動創建向量的向量。語法可以通過可變參數宏(如果編譯器支持它們)和/或輔助模板函數來適應語法來簡化,但這很容易變得混亂。
的C方式(非模板):
使用省略號表示法編寫一個函數,它接受一個參數數目未知的(和類型):
void foo(type x, ...)
這種方法有很多shortcommings。第一個是它不是類型安全的,編譯器將無法檢測到參數是正確的數字或類型,並且如果任何參數是非POD類型,則它是未定義的行爲,這限制了可用性從任何類型到POD類型,這可能或不是一個限制因素(你總是可以傳入一個指向非POD對象的指針)。總的來說,這是更復雜的處理,更容易出錯,所以應該避免。
一點也不
回答這個問題:在極少數情況下,單一的功能應該能夠採取未知數量的未知類型的參數。記錄和I/O可能需要這個,printf
就是這樣的例子。但是這可以通過運算符重載(特別是operator<<
)和鏈接在C++中處理。在評論bind
已經建議,所以是的,在通用代碼完美轉發就是這樣的一個情況下,bind
,std::thread
...
它認爲這是面試的一個很好的答案,你可以再討論一下對功能的實際需求是否存在,以及是否有更好的選擇。可以說,如果最後你確實需要一個變體類型的容器,你可以濫用運算符重載來簡化語法。這方面的例子將是boost::assign
庫,並在這些線路,您可以創建一個輔助論據建設者爲:
class args {
public:
args() {}
operator std::vector<boost::any>&() {
return v;
}
template <typename T>
args& operator,(T x) {
boost::any a = x;
v.push_back(a);
return *this;
}
private:
std::vector<boost::any> v;
};
// usage:
void foo(std::vector<boost::any> a) {
std::cout << "Received " << a.size() << " arguments" << std::endl;
}
int main() {
foo((args(), 1, 5.0, "a string", std::vector<int>(5,10)));
}
可變參數模板
當然,這是一個C++ 0x中最好的選擇編譯器處理可變參數模板,不需要額外的鍋爐代碼,並且可以使編寫用戶代碼(直接作爲常規函數調用)和函數的實現(無論它是什麼)更簡單。作爲一種激勵的例子,建設有可變參數ARGS一個vector<boost::any>
:
typedef std::vector<boost::any> anyvector_t
// Stop condition, adding nothing at the end
void build_vector_impl(anyvector_t&) {}
// Intermediate step, add a new argument to the vector and recurse:
template <typename Head, typename... Tail>
void build_vector_impl(anyvector_t& v, Head head, Tail... tail) {
v.push_back(boost::any(head));
build_vector_impl(v, tail...);
}
// Syntactic sugar: make it return the vector:
template <typename... Args>
anyvector_t build_vector(Args... args) {
anyvector_t res;
build_vector_impl(res, args...);
return res;
}
// Test:
int main() {
std::cout << "Number of args: "
<< build_vector(1, 5, "Hi", std::vector<int>(5, 10)).size()
<< std::endl;
}
Visual Studio確實支持可變宏。 – Puppy 2011-05-21 11:23:43
@DeadMG:更正後,當我和VS一起工作時,我們不得不支持VS2003/05/08,並且可能由於2003年的限制,禁止使用可變宏,因爲它們似乎在2005年可用。感謝提示。 – 2011-05-21 11:59:03
「我仍然在單個函數中找到單一的情況......」std :: bind()? – ybungalobill 2011-05-21 12:07:31
- 1. 功能模板
- 2. 模板功能
- 3. C++模板功能
- 4. Go模板功能
- 5. 從模板功能
- 6. Wikiversity模板功能
- 7. GCC模板功能
- 8. 從模板內綁定模板功能
- 9. 參考模板參數功能模板
- 10. 在模板類使用模板功能
- 11. 轉到模板和功能
- 12. 導出模板功能
- 13. 模板類,功能專業
- 14. 組織模板功能
- 15. docutils/reStructuredText模板功能
- 16. 功能如模板參數
- 17. C++模板交換功能
- 18. 朋友功能和模板
- 19. 模板功能和類
- 20. 模板功能區別
- 21. 覆蓋模板類功能
- 22. 使用功能模板
- 23. 在線模板功能
- 24. C++未能專注功能模板'iterator_traits'
- 25. 帶有編譯VS模板功能的角動態模板?
- 26. 功能模板專業化(以int值爲模板)
- 27. 當模板參數相同時,C++優化類模板功能
- 28. 非模板功能模板類的朋友
- 29. 如何* .INL文件模板類中定義模板功能
- 30. 呼叫從一個模板類中的模板功能
什麼是你的答案嗎? – 2011-05-21 08:49:25
正如我所說,我無法回答 – Vijay 2011-05-21 09:02:47
實際上很抱歉成爲一個學生,但你說:「我不知道確切的答案。」 – 2011-05-21 09:03:40