2014-11-04 58 views
10
#include <iostream> 
#include <array> 

int main(int argc, char **argv) { 
    constexpr const std::array<int, 2> arr {{ 0, 1 }}; 
    constexpr const int arr2[] = { 0, 1}; 

    static_assert(arr[0] == arr2[0], "asdf"); 
    static_assert(arr[1] == arr2[1], "asdfasdf"); 

    return 0; 
} 

gcc 4.8.24.9.1使用g++ test.cpp --std=c++11編譯,編譯成功。 當clang 3.43.5使用clang++ test.cpp --std=c++11然而編譯,編譯失敗:constexpr的std ::陣列static_assert

test.cpp:8:16: error: static_assert expression is not an integral constant expression 
     static_assert(arr[0] == arr2[0], "asdf"); 
         ^~~~~~~~~~~~~~~~~ 
test.cpp:8:16: note: non-constexpr function 'operator[]' cannot be used in a constant expression 

所以我的問題是,它的編譯器是「正確的」,即符合C++ 11的意義嗎?而且,如果clang是正確的,那麼爲什麼std :: array的operator[]不是constexpr的能力?難道這不是std::array應該幫助解決的事情之一嗎?

回答

9

看起來clang是正確的,operator []是不是在C++ 11 constexpr但處於constexpr C++ 14

constexpr const_reference operator[](size_type pos) const; (since C++14) 

-std=c++14所以應編制工作,雖然(see it live)。

C++11 draft standard23.3.2.1類模板陣列概述具有用於operator []以下:

reference operator[](size_type n); 
const_reference operator[](size_type n) const; 

C++14 draft standard有以下幾點:

reference operator[](size_type n); 
constexpr const_reference operator[](size_type n) const; 
^^^^^^^^^ 

更新

C++ 11之後的標準草案N3485包含修復了C++ 11的增強功能。它包含一個constexpr版本的operator []。如果這是缺陷報告的一部分,那麼gcc將是正確的,這似乎是合理的,因爲clang 3.6.0也接受C++ 11模式下的程序。

更新2

我發現,引入的變化,N3470文檔,因爲我無法找到關於這個問題的任何缺陷報告,然後這似乎是一個增強,因此不應該是C++的一部分+11。

+0

在C++ 11中,將'array :: operator [] const'聲明爲'constexpr'已成爲可能,但委員會在C++ 14之前沒有考慮這麼做。在C++ 14中,將'array :: operator []'聲明爲'constexpr'成爲可能...... – Casey 2014-11-04 18:12:54

+1

@Casey我找到了將變更引入'N3485'的文檔,我將其添加到我的答案中。據我瞭解,如果它被認爲是一個缺陷,它應該允許在C + + 11模式,但否則不應該。儘管如此,該文件並沒有闡明。 – 2014-11-04 18:14:43

+1

我大部分時間都喜歡這個標準:庫變化通常落後於核心,因爲核心喜歡在最後一刻進行更改,而沒有給庫提供足夠的時間來做出反應。我相信在N3470中增加constexpr是一個增強,因爲涉及'constexpr'的'array'的唯一缺陷報告是[LWG DR 720](http://www.open-std.org/jtc1/sc22 /wg21/docs/lwg-defects.html#720),它不涉及'operator []'。 – Casey 2014-11-04 18:27:42