Quantcast
Channel: Active questions tagged gcc - Stack Overflow
Viewing all articles
Browse latest Browse all 22220

Template parameter pack expansion failure

$
0
0

Let us consider the following example source in C++:

template <class begin, class... end>struct test {    template <end... beg_vals, begin end_val>    static consteval void make() {    }};int main() {    test<char, int, float>::make<4, 6.f, 'a'>();}

Parameter packs can not be placed at the beginning of a template declaration, but here beg_vals just expand a pack (at least thought so). I thought this program is valid, although is does not compile with either gcc or msvc.

gcc's error message:

<source>: In function 'int main()':<source>:9:46: error: no matching function for call to 'test<char, int, float>::make<4, 6.0e+0f, 'a'>()'    9 |     test<char, int, float>::make<4, 6.f, 'a'>();      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~<source>:4:27: note: candidate: 'template<end ...beg_vals, char end_val> static consteval void test<begin, end>::make() [with end ...beg_vals = {beg_vals ...}; begin end_val = end_val; begin = char; end = {int, float}]'    4 |     static consteval void make() {      |                           ^~~~<source>:4:27: note:   template argument deduction/substitution failed:<source>:9:46: error: conversion from 'float' to 'char' in a converted constant expression    9 |     test<char, int, float>::make<4, 6.f, 'a'>();      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~<source>:9:46: error: could not convert '6.0e+0f' from 'float' to 'char'    9 |     test<char, int, float>::make<4, 6.f, 'a'>();      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~      |                                              |      |                                              float<source>:9:46: error: wrong number of template arguments (3, should be 2)<source>:4:27: note: provided for 'template<end ...beg_vals, char end_val> static consteval void test<begin, end>::make() [with end ...beg_vals = {beg_vals ...}; begin end_val = end_val; begin = char; end = {int, float}]'    4 |     static consteval void make() {      |                           ^~~~Compiler returned: 1

msvc's error message:

example.cpp<source>(4): error C3547: template parameter 'end_val' cannot be used because it follows a template parameter pack and cannot be deduced from the function parameters of 'test<begin,end...>::make'<source>(3): note: see declaration of 'end_val'<source>(4): note: the template instantiation context (the oldest one first) is<source>(2): note: while compiling class template 'test'Compiler returned: 2

At the same time, the program is accepted by modern clang++.

godbolt, case 1

I continued my experiment swapping beginning... and end parameter in make():

template <class begin, class... end>struct test {    template <begin end_val, end... beg_vals>    static consteval void make() {    }};int main() {    test<char, int, float>::make<'a', 4, 6.f>();}

This made msvc to accept the code.

gcc's error message changed, but it continued to "expect two template parameters" in make.

godbolt, case 2

I am pretty sure that gcc is at least wrong at its error message.

My questions are:

  • Is the first source valid?
  • Is the second source valid?
  • Is there a bug report for gcc?

Additionally:

  • Related question with no accepted answer and without template parameters order considering: link.

  • Bug report with similar ICE message: link.


Viewing all articles
Browse latest Browse all 22220


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>