[英]conversion error from make_integer_sequence to integer_sequence
以下程序無法編譯:
#include <utility>
#include <iostream>
#define N 4
template <unsigned int I>
unsigned int g() { return I; }
template <unsigned int... I>
unsigned int f(std::integer_sequence<unsigned int, I...> = std::make_integer_sequence<unsigned int, N>{})
{
return (g<I>() + ...);
}
int main()
{
std::cout << f() << std::endl;
return 0;
}
使用 gcc 錯誤是
main.cpp:在 function 'unsigned int f(std::integer_sequence<unsigned int, I...>) [with unsigned int...I = {}]':
main.cpp:17:18:錯誤:無法將 'std::make_integer_sequence<unsigned int, 4>{}' 從 'integer_sequence<[...],'nontype_argument_pack' 不支持 dump_expr>' 轉換為 'integer_sequence< [...],'nontype_argument_pack' 不支持 dump_expr>'
使用 clang++ 會報告類似的轉換錯誤:
錯誤:沒有從 'std::make_integer_sequence<unsigned int, 4>' (又名 '__make_integer_seq<integer_sequence, unsigned int, 4U>')到 'std::integer_sequence' 的可行轉換
然而,奇怪的是,如果我刪除默認參數,並將相同的表達式傳遞給f
,程序將編譯並給出更正后的 output:
#include <utility>
#include <iostream>
#define N 4
template <unsigned int I>
unsigned int g() { return I; }
template <unsigned int... I>
unsigned int f(std::integer_sequence<unsigned int, I...>)
{
return (g<I>() + ...);
}
int main()
{
std::cout << f(std::make_integer_sequence<unsigned int, N>{}) << std::endl;
return 0;
}
第一個代碼有什么問題/區別?
我承認,我不明白錯誤信息。 第二個版本編譯但不是第一個版本的原因是模板參數不能從默認的 arguments 而是從 function 參數推導出來。 考慮這個更簡單的例子:
#include <utility>
#include <iostream>
template <unsigned int>
struct foo {};
template <unsigned int x>
foo<x> make_foo(){ return {};}
template <unsigned int x>
unsigned int f(foo<x> = make_foo<4>())
{
return 42;
}
int main()
{
std::cout << f() << std::endl;
return 0;
}
這里的錯誤更具描述性:
<source>: In function 'int main()':
<source>:18:18: error: no matching function for call to 'f()'
18 | std::cout << f() << std::endl;
| ^
<source>:11:14: note: candidate: 'template<unsigned int x> unsigned int f(foo<x>)'
11 | unsigned int f(foo<x> = make_foo<4>())
| ^
<source>:11:14: note: template argument deduction/substitution failed:
<source>:18:18: note: couldn't deduce template parameter 'x'
18 | std::cout << f() << std::endl;
| ^
make_integer_sequence<unsigned int,N>
的主要目的是從單個N
轉換到std::integer_sequence<unsigned int, I...>
中的包,就像您在第二個示例中所做的那樣。
使用間接級別,您可以避免調用者必須傳遞參數:
// ...
template <unsigned int... I>
unsigned int f(std::integer_sequence<unsigned int, I...>)
{
return (g<I>() + ...);
}
template <unsigned int X = N>
unsigned int f_wrap()
{
return f(std::make_integer_sequence<unsigned int,N>{});
}
int main()
{
std::cout << f_wrap() << std::endl;
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.