我想解壓一個可變引數模板引數包。由于該函式需要訪問物件的私有成員,所以我決定將其寫為成員函式。據我了解,根據標準,必須在與封閉類相同的命名空間中指定模板函式,我試圖將宣告和定義分開。結果我只收到查找錯誤。
以下是我正在嘗試做的事情的簡短娛樂:
class Container{
private:
//My first try
template<typename... Ts>
void foo();
//Second try
template<> foo();
template<typename T, typename... Ts>
void foo();
}
template<> void Container:foo(){}
template<typename T, typename... Ts>
void Container::foo(){
foo<Ts...>();
}
我應該寫什么而不是注釋部分,或者我在嘗試這個時是否有更普遍的錯誤?
我已經看過諸如遞回可變引數模板之類的問題來列印引數包的內容,但是它們都沒有使用成員函式,因此可悲的是它并沒有真正幫助。
此外,如果引數串列為空,這應該什么都不做。這就是為什么以下不起作用的原因。
template<typename T, typename... Ts>
void foo(){
if constexpr (sizeof...(Ts)){
foo<Ts...>();
}
}
關于錯誤資訊:
對于嘗試 1 -
Container::foo() 不匹配任何模板宣告
對于嘗試 2 -
非命名空間范圍類 Container 中的顯式特化
uj5u.com熱心網友回復:
在 C 20 中,您可以使用模板 lambda 來提取第一個模板引數,如下所示:
class Container {
private:
template<typename... Ts>
void foo();
};
template<typename... Ts>
void Container::foo() {
if constexpr (sizeof...(Ts))
[this]<typename /*First*/, typename... Rest> {
foo<Rest...>();
}.template operator()<Ts...>();
}
演示。
但是與使用遞回相比,折疊運算式(已在其他答案中給出)在您的情況下似乎是一種更有效的方法。
uj5u.com熱心網友回復:
您的第一次嘗試沒有成功,因為宣告template<typename... Ts> void foo();必須與看起來相同的宣告相匹配, nottemplate<typename T, typename... Ts> void foo() { // ...具有不同的模板引數。
在 C 17 中,使用折疊運算式為引數包中的每件事“做某事”非常簡單:
class Container {
private:
template<typename... Ts>
void foo();
};
template<typename... Ts>
void Container::foo() {
// Fold over comma which calls and discards the result of a lambda
(([&]{
// Use `Ts` here. For example:
std::cout << typeid(Ts).name() << '\n';
}()), ...);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/394776.html
上一篇:在教程中找到的代碼的語法錯誤?
