首页 > 解决方案 > C++ 如何说服 constexpr 函数是 constexpr,对于任何类型的参数

问题描述

我找不到与此相关的问题/答案。考虑一下:

// constexpr declares intent

   template <typename T> inline constexpr const bool probe (T const &  ) noexcept { return false; }
   template <typename T> inline constexpr const bool probe (T const *  ) noexcept { return true;  }
   template <typename T> inline constexpr const bool probe (T  &&  ) noexcept = delete ;
   template <typename T> inline constexpr const bool probe (T      ) noexcept = delete ;

众所周知并期望以下在编译时按预期工作:

 constexpr inline const char * holla_ = "Hola!";
 // OK
 static_assert( probe(holla_) );
 // OK
 static_assert( probe("string literal") );

还有这些:

  inline const char buff[]{"ABCD"};
  // OK -- although `buff` is not compile time array
  static_assert( probe( buff ) );

  constexpr inline int const * ip = nullptr ;
  static_assert( probe( ip ) );

但这里是编译时不能做的区域:

   // deliberately omitted constexpr
   inline const char * wot_here_ = "Another literal";

  // error: the value of 'wot_here_' is not usable in a 
  // constant expression
  // note: 'wot_here_' was not declared 'constexpr'
  // static_assert( probe( wot_here_) );

我理解wot_here_的是运行时变量。probe()仅使用参数类型声明和实现。我是否公开违反标准中的一些明显规则?或者巧妙地,反对一些微妙的。

我谨慎地希望有人可以“解决”这个问题?

代码在这里

标签: c++c++17constexprconstant-expression

解决方案


我真的希望有人可以“解决”这个问题?

我看到的唯一“绕过”是 declate wot_her_ constexpr

如果你定义

inline const char * wot_here_ = "Another literal";

你有一个初始化运行时的变量。

观察它const char *是一个指向常量的变量指针char,所以它不是一个常量值,因为你可以递增/递减它。

函数也可以由constexpr运行时变量调用,因此您可以调用

probe( wot_here_)

但是probe(),在这种情况下,是在运行时执行的。

问题是static_assert()必须在编译时执行,所以

static_assert( probe( wot_here_) );

给出错误,因为编译器无法检查运行时执行的编译时间。

我看到的唯一解决方案是和以前wot_here_ constexpr一样定义,holla_因此编译器可以probe(wot_here_)static_assert().


推荐阅读