2017-08-27 110 views
0

按照C++ 17初始化程序規則auto x{123};int但在C++ 11/C++ 14模式不同的編譯器嘗試了這一點,將表明,一些編譯器將它推到一個int,而其他將它演繹到自動初始化typeid的信息

std::initialzer_list<int> 

我使用C++ 17只是爲了測試

#include<iostream> 
#include <typeinfo> 
int main() 
{ 
    auto x{123}; 
    auto y={1,2}; 
    std::cout<<"Type is "<<typeid(x).name()<<std::endl; 
    std::cout<<"Type is "<<typeid(y).name()<<std::endl; 

} 

輸出

Type is i 
Type is St16initializer_listIiE 
Program ended with exit code: 0 

不應它被示出 期望輸出

Type is int 

由於它是存在於以下參考碼

http://en.cppreference.com/w/cpp/language/typeid

回答

4

通過std::type_info::name返回的名稱被實現定義的,它不能保證返回"int"

返回一個實現定義的以NULL結尾的包含類型名稱的字符串。沒有保證;特別是,返回的字符串對於幾種類型可以是相同的,並且在相同程序的調用之間改變。

另一方面,您可以在編譯時獲得類型信息(使用未定義的類模板)。它也取決於編譯器,但通常更清晰。 (這個想法來自Effective Modern C++(斯科特邁爾斯)第4項來了解:如何查看推導類型)

template <typename> 
struct TD; 

int main() 
{ 
    auto x{123}; 
    auto y={1,2}; 

    TD<decltype(x)> td1; 
    TD<decltype(y)> td2; 
} 

然後你會得到從編譯錯誤信息的類型信息,如Clang

source_file.cpp:12:21: error: implicit instantiation of undefined template 'TD<int>' 
    TD<decltype(x)> td1; 
        ^
source_file.cpp:13:21: error: implicit instantiation of undefined template 'TD<std::initializer_list<int> >' 
    TD<decltype(y)> td2; 
        ^
0

與您的代碼x{123}評估爲int,因爲那是你傳入。但是,對於y,你已經傳遞了一個整數列表。它推斷它的一個initializer_list,因爲這是默認類型,在此示例中用於initializer_list構造。

#include <iostream> 
#include <typeinfo> 
#include <initializer_list> 

class Test 
{ 
public: 
    Test(std::initializer_list<int> ints) { 
    for (auto i : ints) 
    { 
     std::cout << i << std::endl; 
    } 
    } 
}; 

int main() 
{ 
    auto x{ 123 }; 
    auto y = { 1,2 }; 
    std::cout << "Type is " << typeid(x).name() << std::endl; 
    std::cout << "Type is " << typeid(y).name() << std::endl; 

    Test t{ 1, 2, 3 }; 

    std::cin.get(); 
} 
+0

我的問題基本上是「我」和「INT」 –

+0

啊之間的差異,那麼,這是實施依賴。 msvc返回int,對於intializer_list,它返回'class std :: initializer_list '。我會說類型信息是安全的比較另一種類型的信息調用,但不是針對一個字符串(如果你想讓你的代碼是可移植的)。 – Josh

+1

@HariomSingh在這種情況下,你的大部分問題是無關緊要的,應該編輯出來。 'int main(){std :: cout << typeid(int).name()<<'\ n'; }'就已經足夠了,沒有必要在'auto'帶來,沒必要在'的std :: initializer_list '帶來,沒必要帶在C++ 11/C++ 14/C++ 17倍的差別。 – hvd