簡體   English   中英

從 make_integer_sequence 到 integer_sequence 的轉換錯誤

[英]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;
}

在 Coliru 上進行現場測試。

使用 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;
}

在 Coliru 上現場觀看

第一個代碼有什么問題/區別?

我承認,我不明白錯誤信息。 第二個版本編譯但不是第一個版本的原因是模板參數不能從默認的 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM