constexpr的推断类型是什么?

the*_*ang 8 c++ templates overloading constexpr c++11

#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);
}
Run Code Online (Sandbox Code Playgroud)

输出是:

const int&
int&&
Run Code Online (Sandbox Code Playgroud)

constexpr变量到底是什么?foo给出的重载const int&.

编辑:继续使用constexpr推断为const T&;

为什么类范围的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();
}
Run Code Online (Sandbox Code Playgroud)

以上无法编译给出错误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);
}
Run Code Online (Sandbox Code Playgroud)

Tar*_*ama 2

N3337 [dcl.constexpr]/9:对象声明中使用的说明符constexpr将对象声明为const。[...]

由于您声明kconstexpr,它也声明为const,因此const int&在重载决策中选择了 。