简体   繁体   English

Constexpr静态成员函数用法

[英]Constexpr static member function usage

Consider the following example code: 请考虑以下示例代码:

#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>();
}

When I try to compile this with GCC 7.3.0, I get an error about h not being usable in a non-constexpr context: 当我尝试使用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;
           ^

However, when I try compiling the exact same code in Clang 6.0.0, it compiles without any errors. 但是,当我尝试在Clang 6.0.0中编译完全相同的代码时,它编译时没有任何错误。 Additionally, when I modify the code to not be inside the templated DoIt() function, GCC compiles this just fine: 另外,当我修改代码不在模板化的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;
}

I already know how to fix the first code so it compiles on GCC using decltype , but I'm curious to know why doesn't the first piece of code compile with GCC? 我已经知道如何修复第一个代码,所以它使用decltype在GCC上编译,但我很想知道为什么第一段代码不能用GCC编译? Is this just a bug in GCC, or is there something I don't understand about using constexpr static member functions? 这只是GCC中的一个错误,还是我对使用constexpr静态成员函数有些不了解?

Looks like a bug to me. 对我来说看起来像个错误。

The type and meaning of the expression h.size() is defined by [expr.ref] "Class member access": 表达式h.size()的类型和含义由[expr.ref] “类成员访问”定义:

[expr.post]/3

Abbreviating postfix-expression.id-expression as E1.E2 , E1 is called the object expression. postfix-expression.id-expression缩写为E1.E2E1称为对象表达式。 [...] [...]

and

[expr.post]/6.3.1

If E2 is a (possibly overloaded) member function, function overload resolution is used to determine whether E1.E2 refers to a static or a non-static member function. 如果E2是(可能是重载的)成员函数,则使用函数重载E1.E2来确定E1.E2是指静态成员函数还是非静态成员函数。

  • (6.3.1) If it refers to a static member function and the type of E2 is “function of parameter-type-list returning T ”, then E1.E2 is an lvalue; (6.3.1)如果它引用静态成员函数并且E2的类型是“参数类型列表返回T函数”,则E1.E2是左值; the expression designates the static member function . 表达式指定静态成员函数 The type of E1.E2 is the same type as that of E2 , namely “function of parameter-type-list returning T ”. E1.E2的类型与E2类型相同,即“参数类型列表返回T函数”。

This means h.size has the same type as ::MyClass::size and is evaluated as such, regardless of the fact that h is constexpr or not . 这意味着h.size::MyClass::size具有相同的类型,并且无论hconstexpr还是not都会被评估。

h.size() is then a call to a constexpr function and is a core constant expression according to [expr.const]/4 . 然后, h.size()调用constexpr函数,并且是[expr.const]/4核心常量表达式

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 通过调用constexpr函数定义静态constexpr成员 - Defining a static constexpr member by call to constexpr function constexpr 使用静态函数初始化静态成员 - constexpr initializing static member using static function 分配 static constexpr 成员等于 static constexpr function? - Assigning static constexpr member equal to static constexpr function? 静态成员函数不被接受为constexpr参数 - Static member function not accepted as constexpr parameter 为什么在调用此constexpr静态成员函数时不将其视为constexpr? - Why is this constexpr static member function not seen as constexpr when called? 位域的默认成员初始化和 constexpr static bool 在预处理器指令中的使用 - default member initialization for bitfields and usage of constexpr static bool in preprocessor directives 在 volatile 成员中使用 constexpr / 静态函数的 C++ 中是否有任何警告? - Are there any caveats in C++ with constexpr / static function usage in volatile members? 使用表达式找不到模板化的静态constexpr成员函数 - static constexpr member function in templated using expression not found static 指向成员的 constexpr 指针 function 向下转型与多个 inheritance - static constexpr pointer to member function downcasting with multiple inheritance std::enable_if 基于使用静态 constexpr 成员函数的表达式 - std::enable_if based on expression using static constexpr member function
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM