hel*_*922 20 c++ static-methods language-lawyer constexpr c++14
请考虑以下示例代码:
#include <array>
struct MyClass
{
size_t value = 0;
constexpr static size_t size() noexcept
{
return 3;
}
};
template <size_t N>
void DoIt()
{
MyClass h;
std::array<int, h.size()> arr;
}
int main()
{
DoIt<1>();
}
Run Code Online (Sandbox Code Playgroud)
当我尝试使用GCC 7.3.0编译它时,我得到一个关于h在非constexpr上下文中不可用的错误:
cexpr.cpp: In function ‘void DoIt()’:
cexpr.cpp:17:26: error: the value of ‘h’ is not usable in a constant expression
std::array<int, h.size()> arr;
^
cexpr.cpp:16:11: note: ‘h’ was not declared ‘constexpr’
MyClass h;
^
cexpr.cpp:17:27: error: the value of ‘h’ is not usable in a constant expression
std::array<int, h.size()> arr;
^
cexpr.cpp:16:11: note: ‘h’ was not declared ‘constexpr’
MyClass h;
^
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试在Clang 6.0.0中编译完全相同的代码时,它编译时没有任何错误.另外,当我修改代码不在模板化DoIt()函数内时,GCC编译就好了:
#include <array>
struct MyClass
{
size_t value = 0;
constexpr static size_t size() noexcept
{
return 3;
}
};
int main()
{
MyClass h;
// this compiles just fine in Clang and GCC
std::array<int, h.size()> arr;
}
Run Code Online (Sandbox Code Playgroud)
我已经知道如何修复第一个代码,因此它在GCC上编译使用decltype,但我很想知道为什么第一段代码不能用GCC编译?这只是GCC中的一个错误,还是我对使用constexpr静态成员函数有些不了解?
对我来说似乎是个虫子。
表达式的类型和含义h.size()由[expr.ref]“类成员访问” 定义:
[expr.post]/3将postfix-expression.id-expression缩写为
E1.E2,E1称为对象表达式。[...]
和
[expr.post]/6.3.1如果
E2是成员函数(可能是重载),则函数重载解析用于确定是E1.E2引用静态成员函数还是非静态成员函数。
- (6.3.1)如果引用静态成员函数并且类型
E2为“返回参数类型列表的函数T”,E1.E2则为左值;该表达式指定静态成员函数。的类型E1.E2与的类型相同E2,即“返回参数类型列表的功能T”。
此装置h.size具有相同的类型::MyClass::size和被评价为这样,不管这一事实h是constexpr或不是。
h.size()然后到一个呼叫constexpr功能,并且是核心常量表达式根据[expr.const]/4。
| 归档时间: |
|
| 查看次数: |
476 次 |
| 最近记录: |