const auto p = &x; でハマった

次のように const auto でポインタを受け取った場合にちとハマったので覚書。

[ソース]

#include <iostream>

struct X{
    void
    print(){
        std::cout << "X::print();" << std::endl;
        std::cout << value << std::endl;
    }

    void
    print() const{
        std::cout << "X::print() const;" << std::endl;
        std::cout << value << std::endl;
    }
    int value;
};

int
main(){
    X x{42};
    const auto p = &x;

    // print() const; が呼ばれない
    p->print();
    return 0;
}

[出力]

X::print();
42


上記のコードですが、期待する動作としては x->print(); 時に print() const; が呼ばれるように思うのですが実際の挙動は異なり、 x->print(); が呼ばれます。
これは p の型が const X* 型ではなくて X* const 型になっているためです。

const auto p = &x;
static_assert(std::is_same<decltype(p), X* const>{}, "");


これを回避する場合は、

const auto* p = &x;
static_assert(std::is_same<decltype(p), const X*>{}, "");


というように記述する必要があります。

[ソース]

#include <iostream>

struct X{
    void
    print(){
        std::cout << "X::print();" << std::endl;
        std::cout << value << std::endl;
    }
    void
    print() const{
        std::cout << "X::print() const;" << std::endl;
        std::cout << value << std::endl;
    }
    int value;
};

int
main(){
    X x{42};
    const auto* p = &x;
    static_assert(std::is_same<decltype(p), const X*>{}, "");

    // print() const; が呼ばれる
    p->print();

    return 0;
}

[出力]

X::print() const;
42


最初、print() const; がないのになんでコンパイルエラーにならないのか不思議だったのですが、こういう理由でした。
auto 周りはもう1回仕様を把握し直したい。