表現値(arg)は有効ですが、SFINAEテストに失敗する可能性はありますか?
あなたが書いた方法S
:はい、可能です。
それは最小限、(ない)作業例は以下:
, typename = std::enable_if_t<std::is_constructible< T, U >::value >
問題がある:あなたが次の行をコメントアウトした場合にコンパイルされませんが、それはコンパイルん上記のコード
#include<type_traits>
template< typename T >
struct S {
template< typename U
, typename = std::enable_if_t<std::is_constructible< T, U >::value >
> explicit S (U&& arg) : value{arg} {}
T value;
};
struct A {};
struct B {
B(A &) {}
};
int main() {
S<B> s(A{});
}
をコンストラクタパラメータを転送していないことを確認します。代わりに、あなたはvalue
の引数として(つまりarg
ある)A
に型右辺値参照の変数への左辺値参照を使用しています。
B
右辺値参照からA
に構築可能ではないとsfinae式が失敗した(正確に)、しかし、あなたは実際にそれが動作するsfinae表現を削除し、パラメータを構築するために、このような参照を使用していません。実際に
は、B
あなたがvalue{arg}
を書くときに使用しているものであるA
への左辺値参照、から構成可能です。
それは次のようにあなたは、むしろS
を書く必要があります。
#include<utility>
// ...
template< typename T >
struct S {
template< typename U
, typename = std::enable_if_t<std::is_constructible< T, U >::value >
> explicit S (U&& arg) : value (std::forward<U>(arg)) { }
T value;
};
は、実際には右のタイプのパラメータを転送するstd::forward
の使用に注意してください。
これは、少なくとも上記の問題を解決し、それはあなたが探していた保証を与える必要があります。