2013-12-09 19 views
25

我不明白爲什麼這個代碼編譯沒有錯誤:迴歸虛空?

#include <iostream> 

template <class T> 
struct Test 
{ 
    static constexpr T f() {return T();} 
}; 

int main() 
{ 
    Test<void> test; 
    test.f(); // Why not an error? 
    return 0; 
} 

它是確定按標準,或者是一個編譯器容忍?

+0

好吧,我知道你允許有,說,'無效美孚(){}無效欄(){回報富();}'。我不確定這一點。 – chris

+1

你的問題是什麼?關於返回'void'(它在C++中一直是合法的)?或者關於'constexpr void'組合? – AnT

+3

也許你應該解釋你認爲錯誤應該是什麼? –

回答

24

這看起來有效利用draft C++11 standard,如果我們看一下部分5.2.3顯式類型轉換(函數符號)款說(重點煤礦):

The expression T(), where T is a simple-type-specifier or typename-specifier for a non-array complete object type or the (possibly cv-qualified) void type, creates a prvalue of the specified type, whose value is that produced by value-initializing (8.5) an object of type T; no initialization is done for the void() case.[...]

措辭非常相似pre C++11

這在constexpr沒關係,即使部分7.1.53說:

The definition of a constexpr function shall satisfy the following constraints:

還包括該子彈:

its return type shall be a literal type;

無效一個文字 C++ 11按照章節3.9款,如果我們再看看第它給適合這種情況下的例外,它說:

If the instantiated template specialization of a constexpr function template or member function of a class template would fail to satisfy the requirements for a constexpr function or constexpr constructor, that specialization is not a constexpr function or constexpr constructor. [ Note: If the function is a member function it will still be const as described below. —end note ] If no specialization of the template would yield a constexpr function or constexpr constructor, the program is ill-formed; no diagnostic required.

正如凱西notedC++14 draft standard無效字面,這是一款3.9類型款說:

A type is a literal type if it is:

,包括:

— void; or

6

查看@Shafik Yaghmour的答案獲取完整信息。

以下段落禁止這對於非模板(7.1.5(3)):

The definition of a constexpr function shall satisfy the following constraints:

  • [...]

  • its return type shall be a literal type or a reference to literal type

爲了詳細描述,文字類型是在3.9(10)定義爲標量類型或組合物數組或結構中的文字類型對象。 void不是3.9(9)的標量類型。

+1

*文字類型*在3.9/10中定義;在C++ 11中'void'不*是一個字面類型。在C++ 14(N3797)中,'void' *被包含在文字類型中。所以OP的代碼將符合C++ 14。 – Casey

+2

@Casey我也認爲7.1.5的第6段允許在C++ 11 –

+1

@ShafikYaghmour啊,我同意。有趣的是:這段代碼專門用於C++ 11中的非'constexpr',但'const'成員函數,或C++ 14中的'constexpr'和非'const'成員函數! – Casey

1

你的函數返回的值爲void(),你不是從void函數本身返回的。您正在返回一個NULL值。你在做什麼等同於:

void f() { return void(); } 

這將返回一個空值,唯一的空值。你不能從void函數返回任何其他的東西,因爲它將是一個不同的類型。

+0

我很確定這是由C++ 5.2.3(2)允許的,儘管IANALL。 – filmor

+0

它被編譯器允許,但它並不真正有用,因爲它沒有任何價值。 – user3084096

+2

談論語言標準時,這不是重點。 – filmor