none
std::is_same にある型を指定した時、予想外の挙動を示したが、それは何故? RRS feed

  • 質問

  • 下記のように std::is_same を使用時、予想外の結果になってしまいました。その理由をもしご存知でしたら伺えないでしょうか?  尚、VC++14.1 ( VS2017のVC++ ) と、 g++6.3( オンラインコンンパイラ ideone )

    で、同じ症状を確認しました。

    ----------------------ここから下が、問題のコード----------------------

    // ※ #include 等の非本質コードは略。

    template< typename T >
    struct S{
         typedef const T      type;   // const は、Tがポインタ型や参照型を指定時は、削られる。

    };

    int main(){

            // int* と S< int* >::type は、同じ型である事を期待した。が、下記3.が予想外の結果だった。


            // 1. type_info::name() では、両者が同じ型名を示した。予想通り。

            printf( "%s %s\n", typeid( int* ).name(), typeid( S< int* >::type ).name() );

            // 2. 実際に使う時も、予想通りに使えた。

            int                        v{ 1234 };

            S< int* >::type     p{ &v };

            printf( "%d\n", *p ); // 1234 を表示する。


            // 3. std::is_same で両者が合致せず、下記の静的表明は失敗してしまう。なぜ?

            static_assert( std::is_same< S< int* >::type, int* >::value, "" );

     }

    2017年7月8日 2:12

回答

  • S<int*>::typeはint*ではなくint* constです。std::is_sameは正しく判定したまでです。もちろん

    static_assert(std::is_same<S<int*>::type, int* const>::value, "");

    なら期待通り成功します。

    なお、

    • const int*はpointer to const int、つまりポインターは変更可で、ポインターの指している先のint値は変更不可です。
    • int* constはconst pointer to int、つまりポインターは変更不可で、ポインターの指している先のint値は変更可です。

    2017年7月8日 5:38