mardi 21 août 2018

calling a template parameter constexpr method?

std::array<...>::size() is a non-static constexpr method; being constexpr I can use it as a template parameter:

#include <array>
#include <stdio>

int main(void) {
  std::array<char, 12> a = Hello world;
  std::cout << "size() = " << a.size() << ", data() = \"" << a.data() << "\"" << std::endl;

  std::array<char, a.size()> b = a;
  std::cout << "size() = " << b.size() << ", data() = \"" << b.data() << "\"" << std::endl;
}

However, if the std::array<...> is a template parameter, things become uncertain:

template <typename T>
void copy(T const& a) {
  std::array<char, a.size()> c = a;
  std::cout << "size() = " << c.size() << ", data() = \"" << c.data() << "\"" << std::endl;
}

GCC happily compiles this [1], while CLANG refuses [2] with

<source>:6:20: error: non-type template argument is not a constant expression
  std::array<char, a.size()> c = a;

[1] https://godbolt.org/z/Ru7Y3F
[2] https://godbolt.org/z/LYJcpo

Which one is correct, according to the standard ?


P.S. Yes, I know that I can work around it using std::tuple_size:

template <typename T>
void copy(T const& a) {
  std::array<char, std::tuple_size<T>::value> c = a;
  std::cout << "size() = " << c.size() << ", data() = \"" << c.data() << "\"" << std::endl;
}

Aucun commentaire:

Enregistrer un commentaire