25

std::remove_constに変換しないconst T&のはなぜT&ですか? この確かに不自然な例は、私の質問を示しています。

#include <type_traits>

int main()
{
    int a = 42;
    std::remove_const<const int&>::type b(a);

    // This assertion fails
    static_assert(
        !std::is_same<decltype(b), const int&>::value,
        "Why did remove_const not remove const?"
    );

    return 0;
}

上記のケースは簡単に修正できるので、コンテキストとして次のことを想像してください。

#include <iostream>

template <typename T>
struct Selector
{
    constexpr static const char* value = "default";
};

template <typename T>
struct Selector<T&>
{
    constexpr static const char* value = "reference";
};

template <typename T>
struct Selector<const T&>
{
    constexpr static const char* value = "constref";
};

int main()
{
    std::cout
        << Selector<typename std::remove_const<const int&>::type>::value
        << std::endl;

    return 0;
}

reference上記の例では、 ではなく が表示されることを期待していますconstref

4

1 に答える 1

25

std::remove_const最上位の 資格を削除しますconstconst T&と同等のではT const&、修飾はトップレベルではありません。実際、参照自体には適用されません (参照は定義により不変であるため、意味がありません) が、参照される型に適用されます。

C++11 標準のパラグラフ 20.9.7.1 の表 52 では、以下について指定されていますstd::remove_const

メンバーの typedef 型は、最上位のconst 修飾子が削除されていることをT除いて、 と同じ型を指定する必要があります。[:は に評価され ますが、 はに評価されます。—終了例]remove_const<const volatile int>::typevolatile intremove_const<const int*>::typeconst int*

剥がすconstには、最初に apply std::remove_reference次にapply std::remove_const、(必要に応じて) apply std::add_lvalue_reference(またはケースに適したもの) にする必要があります。

注: Xeoがコメントで言及しているように、最初の 2 つの手順を実行するなどのエイリアス テンプレートの使用をUnqualified検討することができます。つまり、参照を取り除き、次にconst- (およびvolatile-) 修飾を取り除きます。

于 2013-04-08T19:26:05.093 に答える