これは MSVC のバグのようです。形式の式T()
(標準に関する限り、明示的な型変換) を使用すると、指定された型の prvalue が得られます。
式はT()
、配列ではない完全なオブジェクト型または (おそらく cv 修飾された)型T
のsimple-type-specifierまたはtypename-specifiervoid
であり、指定された型の prvalue を作成します。これは値で初期化されます。
const
非クラスの prvalues は cv 修飾された型を持つことができないという規則により、無視されるのは非クラスの型の場合のみです。
クラスの prvalue は、cv 修飾された型を持つことができます。非クラスの prvalues は常に cv 修飾されていない型を持ちます。
T()
したがって、ここで作成された一時オブジェクトは、メンバー関数const
を呼び出す必要があります。const
いつ、どのような理由で を使用するかについては、提案std::add_const
に含めた理由を確認できます。、、、、およびタイプの特性が提案から削除されたが、Boost のユーザーからの苦情を受けて元に戻されたと述べています。add_const
add_volatile
add_cv
add_pointer
add_reference
理論的根拠は、これらのテンプレートはすべて、ある型を別の型に変換するコンパイル時のファンクターとして使用されるということです [...]
与えられた例は次のとおりです。
// transforms 'tuple<T1,T2,..,Tn>'
// to 'tuple<T1 const&,T2 const&,..,Tn const&>'
template< typename Tuple >
struct tuple_of_refs
{
// transform tuple element types
typedef typename mpl::transform<
typename Tuple::elements,
add_reference< add_const<_1> > // here!
>::type refs;
typedef typename tuple_from_sequence<refs>::type type;
};
template< typename Tuple >
typename tuple_of_refs<Tuple>::type
tuple_ref(Tuple const& t)
{
return typename tuple_of_refs<Tuple>::type(t);
}
mpl::transform
関数ポインターに相当するコンパイル時のメタプログラミングを 2 番目のテンプレート引数として取ると考えることができます-add_reference<add_const<...>>
は の各型に適用されTuple::elements
ます。これは単に を使用して表現できませんでしconst
た。