7

Consider the following snippet of code:

#include<array>
#include<cstdint>

const std::array<int, 3> array{0, 1 , 2};

template<class string_type>
auto parse(string_type&& name) {
        const auto s = std::uint8_t{array.size()};
        return s;
}

While it compiles using gcc 9.3.0 (the default on Ubuntu 20.04), it fails with gcc 11.2.0 (built from sources) with the following error message:

test2.cpp: In function ‘auto parse(string_type&&)’:
test2.cpp:8:47: error: no matching function for call to ‘std::array<int, 3>::size(const std::array<int, 3>*)’
    8 |         const auto s = std::uint8_t{array.size()};
      |                                     ~~~~~~~~~~^~
In file included from test2.cpp:1:
/opt/modules/install/gcc/11.2.0/include/c++/11.2.0/array:176:7: note: candidate: ‘constexpr std::array<_Tp, _Nm>::size_type std::array<_Tp, _Nm>::size() const [with _Tp = int; long unsigned int _Nm = 3; std::array<_Tp, _Nm>::size_type = long unsigned int]’
  176 |       size() const noexcept { return _Nm; }
      |       ^~~~
/opt/modules/install/gcc/11.2.0/include/c++/11.2.0/array:176:7: note:   candidate expects 0 arguments, 1 provided

Running example

Besides the fact that it does not make much sense, I can't find where is the error, can you help me?

4
  • 1
    Something is wrong with your build of the compiler. ‘auto parse(string_type&&)’: -- rvalue string is actually return value type, gcc somehow treated it as parameter. and in array.size gcc treated implicit this as explicit parameter. Commented Oct 27, 2021 at 16:44
  • It seems a gcc bug. It's also reproducible with a "simplified" snippet. Commented Oct 27, 2021 at 21:06
  • Suggest filing a bug. Commented Oct 27, 2021 at 21:59
  • Yep, problem is that i am not sure on what to search to find similar bug. Opened bug 102980, hopefully is not a duplicate. Commented Oct 28, 2021 at 7:37

1 Answer 1

2

It appears to be a bug in:

It works fine in:

To work around, you can do either this:

const auto s = static_cast<std::uint8_t>(array.size());

or this:

const std::uint8_t s = array.size();

or this (but please don't):

const auto s = std::uint8_t( array.size() );

I would suggest this:

#include<array>
#include<cstdint>

const std::array<int, 3> array{ 0, 1 , 2 };

template<class string_type>
auto parse(string_type&& name)
{
    const std::uint8_t s = array.size();
    return s;
}

Running example

Sign up to request clarification or add additional context in comments.

2 Comments

Even with std::uint64_t does not work. Btw, I should have the narrowing warning only when the size of the array is greater than 256, is it correct?
@a_random_user hmm... it seems to be related to it being a function template: godbolt.org/z/847aPboE8

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.