まもなく、参照またはconst型へのポインタがconst型ではないためです。
decltype(*bar)
はconst foo
ではありません。それはconst foo &
であり、実際には異なる獣です。
はhere与えられた例を考えてみましょう:
std::cout << std::is_const<const int *>::value << '\n'; // false
std::cout << std::is_const<int * const>::value << '\n'; // true
我々はstd::is_const<const int *>::value
がfalseでstd::is_const<int * const>::value
が真であることがわかります。
const int *
では、型がconstのポインタであり、それはis_const
(実際には標準)の意図したconst型ではないからです。 int * const
では、const修飾子はポインタータイプに適用され、ポインタータイプには適用されません。したがって、ポインタータイプに関係なく、constタイプになります。
何か同様のものがconst foo &
に適用されます。これはconstの参照です。
あなたは代わりに、これを使用して解決することができます:
static_assert(std::is_const<std::remove_reference_t<decltype(*bar)>>::value, "expected const but this is non-const!");
、あるいはこれ、あなたが実際に*bar
を行う必要はありませんのために:この場合
static_assert(std::is_const<std::remove_pointer_t<decltype(bar)>>::value, "expected const but this is non-const!");
、でポインタを削除/参照とremove_pointer_t
/remove_reference_t
あなたのタイプはconst foo
になります。これは実際にはconstタイプです。サイドノートとして
、上記の例は、C++ 14っぽいstd::remove_reference_t
とstd::remove_pointer_t
型形質を使用します。
それは次のように、簡単にC++ 11にコードのこれらの行を変えることができます:
static_assert(std::is_const<typename std::remove_pointer<decltype(bar)>:: type>::value, "expected const but this is non-const!");
より多くの詳細を与えるためにその答えにいくつかのコメントを言及する価値があります:
'const foo * bar'はconst _pointer_を作成しますが、それが指す値は_not_ constです。 – Aganju
@Aganjuいいえ、それは 'foo * const bar;です。 – greatwolf
' const foo * bar'は 'foo const * bar'と同じですが、' foo * const bar'とは異なります –