Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

C++ template specialization changes constexpr rules?

I am using g++ (GCC) 11.2.0.

The following piece of code

#include <vector>
#include <iostream>

template<int size>
constexpr std::vector<int> get_vector() {
        return std::vector<int> (size);
}

int main() {
        std::cout << get_vector<5>().size() << std::endl;
}

compiles successfully and outputs 5 when executed. Just as I expected.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

However, if I add specialization

#include <vector>
#include <iostream>

template<int size>
constexpr std::vector<int> get_vector() {
        return std::vector<int> (size);
}

template<>
constexpr std::vector<int> get_vector<2>() {
        return std::vector<int> (2);
}

int main() {
        std::cout << get_vector<5>().size() << std::endl;
}

it fails to compile and produces the error

another.cpp: In function ‘constexpr std::vector<int> get_vector() [with int size = 2]’:
another.cpp:10:28: error: invalid return type ‘std::vector<int>’ of ‘constexpr’ function ‘constexpr std::vector<int> get_vector() [with int size = 2]’
   10 | constexpr std::vector<int> get_vector<2>() {
      |                            ^~~~~~~~~~~~~
In file included from /usr/include/c++/11.2.0/vector:67,
                 from another.cpp:1:
/usr/include/c++/11.2.0/bits/stl_vector.h:389:11: note: ‘std::vector<int>’ is not literal because:
  389 |     class vector : protected _Vector_base<_Tp, _Alloc>
      |           ^~~~~~
/usr/include/c++/11.2.0/bits/stl_vector.h:389:11: note:   ‘std::vector<int>’ has a non-trivial destructor

Why does it happen?

>Solution :

If you take a look at compiler support you will find out that gcc supports constexpr std::vector from version 12. As you tell us you use gcc 11.2 it simply is not implemented in the library.

You can see it working as expected on godbolt with trunk versions of gcc and clang. For gcc it will be part of gcc 12.x versions.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading