constexpr 的推导类型是什么?

What is the deduced type of a constexpr?

#include <iostream>
#include <string>

void foo(int& k) { std::cout << "int&\n"; }
void foo(int&& k) { std::cout << "int&&\n"; }
void foo(const int& k) { std::cout << "const int&\n"; }
void foo(const int&& k) { std::cout << "const int&&\n"; }    
int main() {
  static  constexpr int k = 1;
  foo(k);
  foo(1);
}

输出为:

const int&
int&&

constexpr 变量究竟被视为什么? foo 的重载给出 const int&.

编辑:继续将 constexpr 推导为 const T&

为什么 class 范围内的 constexpr 无法传递给采用通用引用的函数?!

#include <type_traits>

template <typename T>
void goo(T&& k) {
  static_assert(std::is_same<decltype(k), const int&>::value, "k is const int&");
}

class F {
  static  constexpr int k = 1;
public:
  void kk2 () { goo(k); }
};

int main () {
  F a;
  a.kk2();
}

以上编译失败undefined reference to F::k 但是以下通过:

#include <type_traits>

template <typename T>
void goo(T&& k) {
  static_assert(std::is_same<decltype(k), const int&>::value, "k is const int&");
}

int main() {
  static  constexpr int k = 1;
  goo(k);
}

N3337 [dcl.constexpr]/9: A constexpr specifier used in an object declaration declares the object as const. [...]

既然你把k声明为constexpr,它也声明为const,所以在重载决策中选择了const int&

foo(1);

在这种情况下,一个值为 1 的临时变量被传递给函数 foo,因此是非常量右值。

/*static*/ constexpr int k = 1;
foo(k);

这里将一个值为 1 的命名常量变量传递给函数 foo,因此为常量左值。 static 关键字对函数范围内的 constexpr 变量没有影响。

What exactly is a constexpr variable treated as?

当用在不是常量表达式的表达式中时,constexpr 变量只是一个 const 变量。

Why does a constexpr at class scope fail to be passed to a function taking universal reference?!

您收到链接器错误,因为您在未定义变量的情况下使用了该变量。您需要在一个翻译单元中的名称空间范围内定义 F::k,就像您在 C++98 中对 static const 成员变量所做的那样。