2017-01-09 13 views
20

私はhttp://en.cppreference.com/w/cpp/language/typeidを参照して、さまざまなタイプの異なることをするコードを記述しました。変数のstd :: stringの型IDと引数のstring?

コードは以下の通りであり、コメントに説明があります。

#include <iostream> 
#include <typeinfo> 

using namespace std; 

template <typename T> 
void test_template(const T &t) 
{ 
    if (typeid(t) == typeid(double)) 
     cout <<"double\n"; 
    if (typeid(t) == typeid(string)) 
     cout <<"string\n"; 
    if (typeid(t) == typeid(int)) 
     cout <<"int\n"; 
} 

int main() 
{ 
    auto a = -1; 
    string str = "ok"; 
    test_template(a); // Prints int 
    test_template("Helloworld"); // Does not print string 
    test_template(str); // Prints string 
    test_template(10.00); // Prints double 

    return 0; 
} 

なぜtest_template("Helloworld")に対しtest_template(str)プリント "の文字列" しないのですか?

ところで、私のG ++バージョンは、++(〜16.04.4 Ubuntuの5.4.0-6ubuntu1)"Helloworld"などの5.4.0 20160609.

+17

なぜdownvotes?確かに、それは基本的なレベルですが、問題は完全で明確であり、OPにはコンパイラバージョンも含まれています! – TartanLlama

+3

'' Helloworld ''は' std :: string'ではありません。しかし、 "" Helloworld "sはそうだろう。 – Jarod42

+2

@TartanLlama:ひどく壊れやすいコードを書くために 'typeid'を使いたいと思うユーザのためだと思います。 –

答えて

22

このコール

test_template("Helloworld"); // Does not print string 

で引数"Helloworld"const char[11]型を持つリテラル文字列です。

関数のパラメータは、参照タイプ

void test_template(const T &t) 
          ^^^ 

は、関数内の引数(より正確にパラメータ)タイプconst char (&t)[11]を有しているので。

C++の文字列リテラルには、文字列リテラルの文字数に終端のゼロを加えた数の要素を持つ定数文字配列型があります。変数strはそれにもかかわらずオブジェクト自体は型であるリテラル"ok"文字列で初期化された

string str = "ok"; 
^^^^^^ 

のように宣言されているため

このコール

test_template(str); 

では引数がstd::stringを入力したstd::string

+1

'conat char'は' const char'ですか? (私は1回の変更で編集を提出することはできません) –

+0

@ChristopheStrobbeあなたはどういう意味ですか? –

+0

あなたの答えは、conat char(&t)[11] 'の' conat'です。 –

9

文字列リテラルは、文字の定数配列ですgです。

std::stringクラスには、文字列リテラルへのポインタを取るコンストラクタがありますが、文字列リテラル自体はstd::stringオブジェクトではありません。


あなたのような機能を使用することは、コードの匂いと悪いデザインとみなされます。代わりに、異なる引数を取るオーバーロードされた関数を使用してください。それは文字列の問題も解決します。

+3

合意されて、ここにテンプレートを持つことには意味がありません。共通の機能はありません。 – AndyG

+1

ありがとう!代わりに、オーバーロードされた関数の使用を検討します。 – Meehatpa

16

C++の文字列リテラルは、タイプconst char[N+1]です。ここで、Nは文字列の文字数です。 std::stringは、文字列を所有し、その上にいくつかの操作を提供する標準ライブラリクラスです。 std::stringconst char[N]から構成できますが、同じものではありません。

関連する問題