Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is templated constexpr with std::string allowed in gcc?

Why is the template version allowed to compile in gcc? Is it a compiler bug or is it actually valid when used with templates? Can someone explain this to me, please?

It does not compile on clang or other compilers used on godbolt.org.

The compile errors generates from both string and stringstream being used in a constexpr.

#include <iostream>
#include <string>
#include <sstream>

template<typename T>
constexpr std::string func1(T a, T b) //Compiles and runs
{
  std::stringstream ss;
  ss << a << b << a+b;
  return ss.str();
}

constexpr std::string func2(int a, int b) //Compile error
{
  std::stringstream ss;
  ss << a << b << a+b;
  return ss.str();
}

int main()
{
  int a = 5;
  int b = 7;
  std::cout << func1(a,b) << std::endl;
  return 0;
}
like image 339
mantler Avatar asked Mar 21 '17 11:03

mantler


People also ask

Can a std :: string be constexpr?

constexpr Containers and Algorithms in C++20C++20 supports the constexpr containers std::vector and std::string. constexpr means in this case, that the member functions of both containers can be applied at compile-time.

What does constexpr mean in c++?

constexpr indicates that the value, or return value, is constant and, where possible, is computed at compile time. A constexpr integral value can be used wherever a const integer is required, such as in template arguments and array declarations.

Does constexpr imply static?

A constexpr specifier used in an object declaration or non-static member function (until C++14) implies const . A constexpr specifier used in a function or static data member (since C++17) declaration implies inline .


1 Answers

GCC could be in the right here. According to dcl.constexpr paragraph 6:

If the instantiated template specialization of a constexpr function template or member function of a class template would fail to satisfy the requirements for a constexpr function or constexpr constructor, that specialization is still a constexpr function or constexpr constructor, even though a call to such a function cannot appear in a constant expression. If no specialization of the template would satisfy the requirements for a constexpr function or constexpr constructor when considered as a non-template function or constructor, the template is ill-formed, no diagnostic required.

The program is ill-formed (std::string is not a literal type) but it is not required to emit a diagnostic.

like image 92
user7744704 Avatar answered Sep 25 '22 19:09

user7744704