を移動する2つのコンストラクタを組み合わせて、自分のおもちゃのクラステンプレートの一つは、非常によく似て2つのコンストラクタを持っています?をコピーして、現在
template<typename U>
optional(U&& x)
{
construct(std::forward<U>(x));
}
を移動する2つのコンストラクタを組み合わせて、自分のおもちゃのクラステンプレートの一つは、非常によく似て2つのコンストラクタを持っています?をコピーして、現在
template<typename U>
optional(U&& x)
{
construct(std::forward<U>(x));
}
に結合するそのようなstd::is_constructible
とstd::is_convertible
などの形質がoptional
と相互作用する方法を変化させます。たとえば、与えられた:
0
をしかし、あなたの新しいコードが印刷されます::
class A {};
int main()
{
std::cout << std::is_constructible<optional<A>, int>::value << '\n';
};
あなたの元のコードは、プリントアウトでしょう
1
を、これは望ましくない、とあなたはまだしたい場合あなたの新しいコードと一緒に行くと、enable_if
それは許容できる種類にU
を制限することができます。
他の可能性のある問題は、T
が参照型(例:int&
)の場合のみです。その場合、元のコードの2番目のコンストラクタはrvalueを渡しているように疑わしくなり、そのrvalueを非const lvalue参照にバインドしようとしている可能性があります。 T
が決してリファレンスタイプでない場合は、これについて心配する必要はありません。
テンプレート化されたコンストラクタは、コピーコンストラクタであることは決してありません。
Erm、 'optional(const T&)'はコピーコンストラクタでさえも、私は何を考えていましたか? – fredoverflow
@Fred:その場合は、C++ 11コンストラクタの転送を使用することを検討してください。まだコンパイラによって実装されている場合。私はどのコンパイラがそれをサポートしているか分からない。サポートされていない場合は、人工基本クラスを使用できます。コンストラクタを呼び出して基本クラスを呼び出します。 –
ああ、 'construct'はコンストラクタではなく、メンバ関数テンプレートです。 – fredoverflow
ああ、constructorはコンストラクタではなく、メンバー関数テンプレートです。
おそらくセマンティクスが異なります。オリジナルのオーバーロードセットは、左辺値参照または右辺値参照のどちらかをconstに渡します。テンプレートバージョンは、左値参照を非 -constに渡すこともできます。 (私はCONSTへの右辺値参照を無視しています。)
すべてのしやすでconstruct
はどちらかであるU&&
を受け入れることを宣言した(他のT
を移動し、あなたの前の過負荷が動作しないでしょう)、この場合、が非で契約がすべきにもかかわらず-const lvalues、またはU const&
を受け入れると宣言されており、この場合は無害です。
あなたは、少なくともconstruct(const T& x)
、おそらく定義されconstruct(T&& x)
の追加を持っている、とタイプU
のあなたのオブジェクトのタイプT
のオブジェクトに変換可能であると仮定すると、私はあなたが問題ないはずだと思う...
construct(const T& x)
U
意志の一時的なR値を結合するタイプU
のL値基準は、construct(const T& x)
U
の非定数L値基準を結合しますconstruct(T&& x)
又はconstruct(const T& x)
に結合し、R値の基準バージョンをU
の定数r値の基準を定義されていない場合は、construct(const T& x)
'construct 'の実際の肉は何ですか? –
@Alf:整列したストレージ上の醜い配置新しいもの:) – fredoverflow