簡體   English   中英

Constexpr靜態成員函數用法

[英]Constexpr static member function usage

請考慮以下示例代碼:

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

當我嘗試使用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;
           ^

但是,當我嘗試在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;
}

我已經知道如何修復第一個代碼,所以它使用decltype在GCC上編譯,但我很想知道為什么第一段代碼不能用GCC編譯? 這只是GCC中的一個錯誤,還是我對使用constexpr靜態成員函數有些不了解?

對我來說看起來像個錯誤。

表達式h.size()的類型和含義由[expr.ref] “類成員訪問”定義:

[expr.post]/3

postfix-expression.id-expression縮寫為E1.E2E1稱為對象表達式。 [...]

[expr.post]/6.3.1

如果E2是(可能是重載的)成員函數,則使用函數重載E1.E2來確定E1.E2是指靜態成員函數還是非靜態成員函數。

  • (6.3.1)如果它引用靜態成員函數並且E2的類型是“參數類型列表返回T函數”,則E1.E2是左值; 表達式指定靜態成員函數 E1.E2的類型與E2類型相同,即“參數類型列表返回T函數”。

這意味着h.size::MyClass::size具有相同的類型,並且無論hconstexpr還是not都會被評估。

然后, h.size()調用constexpr函數,並且是[expr.const]/4核心常量表達式

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM