我想計算通過模板傳遞的所有引數(非型別引數)的總和。我編譯了以下程式:g -std=c 17 -g -Wall -o main main.cpp。似乎我錯過了一些東西,因為我在編譯時遇到了這個錯誤:
error: call of overloaded ‘func<N_0>()’ is ambiguous
std::cout << func<N_0>() << std::endl;
error: call of overloaded ‘func<22>()’ is ambiguous
return N func<Next... >();
#include <iostream>
using namespace std;
template <std::size_t T>
std::size_t sum()
{
return T;
}
template <std::size_t N, std::size_t ...Next>
std::size_t sum()
{
return N sum<Next... >();
}
int main()
{
const size_t N_0 = 4;
const size_t N_1 = 11;
const size_t N_2 = 22;
std::cout << sum<N_0>() << std::endl;
std::cout << sum<N_0, N_1, N_2>() << std::endl;
return 0;
}
我發現了很多這樣的例子:
#include <iostream>
template<typename T>
T adder(T first) {
return first;
}
template<typename T, typename... Args>
T adder(T first, Args... args) {
return first adder(args...);
}
int main() {
const int c = adder(1, 8, 4);
std::cout << c << '\n';
return 0;
}
我很好奇為什么我的代碼不起作用。
uj5u.com熱心網友回復:
在第一個和第二個代碼示例中,僅使用一個(模板)引數呼叫函式會導致兩個函式模板都是可行的。包將只是空的。
然而,在第二個例子的多載決議中,可變引數模板被認為不如非可變引數模板專門化,主要是因為呼叫它的可能引數集是可以呼叫非可變引數模板的超集。這只是因為函式引數中的引數包。因此,多載決議將更喜歡非可變模板作為決勝局。
此順序不適用于您的第一個代碼示例,其中兩個模板的函式引數相同。
因此,在您的第一個代碼示例中,使用單個(模板)引數的多載決議是模棱兩可的,但在第二個代碼示例中并不模棱兩可。
您可以指定可變引數模板至少需要兩個引數來解決歧義:
template <std::size_t N, std::size_t M, std::size_t ...Next>
std::size_t sum()
{
// May wrap-around to zero
return N sum<M, Next... >();
}
但是,在 C 17 及更高版本中,sum可以通過使用折疊運算式將整個構造簡化為:
template <std::size_t ...Ns>
std::size_t sum()
{
// May wrap-around to zero
return (Ns ...);
}
(這個函式可能應該在 C 17 或C 20 中被標記noexcept,并且應該小心許多/大的引數,因為如果總和變得太大而無法容納,加法將默默地環繞。)constexprconstevalstd::size_t
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/405352.html
標籤:
上一篇:組合-將錯誤映射到不同型別
