2012-11-09 42 views
6
template<typename T> 
void print_size(const T& x) 
{ 
    std::cout << sizeof(x) << '\n'; 
} 

int main() 
{ 
    print_size("If you timidly approach C++ as just a better C or as an object-oriented language, you are going to miss the point."); 
    // prints 115 
} 

これは最近のg ++​​コンパイラに115を出力します。だから明らかに、Tは(ポインタの代わりに)配列になると推測されます。その動作は標準によって保証されていますか?次のコードはポインタのサイズを出力するので、私はちょっと驚いていました。autoはテンプレート引数の控除のように振る舞いましたか?文字列リテラルのテンプレート引数の控除

int main() 
{ 
    auto x = "If you timidly approach C++ as just a better C or as an object-oriented language, you are going to miss the point."; 
    print_size(x); 
    // prints 4 
} 
+1

前者は今はしませんが、後者は予期しないことではありません。文字列リテラルは配列ですか、そうではありませんか? – Tomek

+2

これを知らない人は誰でも知りません:配列を値渡しで渡すことはできません(ポインタに崩壊する)が、配列への参照を渡すことはできます。ここで、 'const T&'は配列への参照になり、 'sizeof'は配列のサイズを与えます。 –

+1

Martinhoの答えが主な質問をカバーしています。 forは、14.8.2.1/2の動作を保証しています: "' P'が参照型でない場合: 'A'が配列型の場合は、配列からポインタへの標準変換によって生成されたポインタ型が、 'A'は型減算; ..."は 'P'はテンプレート関数の関数パラメータの型であり、' A'は関数呼び出しで使われる式の型です。 – aschepler

答えて

8

autoテンプレート引数控除のよう正確に動作します。正確にTのように!これにより

template<typename T> 
void print_size(T x) 
{ 
    std::cout << sizeof(x) << '\n'; 
} 

int main() 
{ 
    print_size("If you timidly approach C++ as just a better C or as an object-oriented language, you are going to miss the point."); 
    // prints 4 
    auto x = "If you timidly approach C++ as just a better C or as an object-oriented language, you are going to miss the point."; 
    print_size(x); 
    // prints 4 
} 

は、これを比較し

template<typename T> 
void print_size(const T& x) 
{ 
    std::cout << sizeof(x) << '\n'; 
} 

int main() 
{ 
    print_size("If you timidly approach C++ as just a better C or as an object-oriented language, you are going to miss the point."); 
    // prints 115 
    const auto& x = "If you timidly approach C++ as just a better C or as an object-oriented language, you are going to miss the point."; 
    print_size(x); 
    // prints 115 
} 

ないかなりが、これはコーナーケースの一つではありません。

+0

愚かな私。カーテンを持ち上げてくれてありがとう:) – fredoverflow

+0

もちろん、Cスタイルの配列をC++の値として渡すことはできません。 – Yakk

+0

@ヤク:確かに、それはCの互換性を損なうだろうから。 Cは参照を持たなかったので、既存の動作はありませんでした。 – MSalters

関連する問題