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
成员变量所做的那样。
#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:
Aconstexpr
specifier used in an object declaration declares the object asconst
. [...]
既然你把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
成员变量所做的那样。