2011-09-12 11 views
7

を移動する2つのコンストラクタを組み合わせて、自分のおもちゃのクラステンプレートの一つは、非常によく似て2つのコンストラクタを持っています?をコピーして、現在

template<typename U> 
optional(U&& x) 
{ 
    construct(std::forward<U>(x)); 
} 
+0

'construct 'の実際の肉は何ですか? –

+0

@Alf:整列したストレージ上の醜い配置新しいもの:) – fredoverflow

答えて

2

に結合するそのようなstd::is_constructiblestd::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が決してリファレンスタイプでない場合は、これについて心配する必要はありません。

4

テンプレート化されたコンストラクタは、コピーコンストラクタであることは決してありません。

+0

Erm、 'optional(const T&)'はコピーコンストラクタでさえも、私は何を考えていましたか? – fredoverflow

+0

@Fred:その場合は、C++ 11コンストラクタの転送を使用することを検討してください。まだコンパイラによって実装されている場合。私はどのコンパイラがそれをサポートしているか分からない。サポートされていない場合は、人工基本クラスを使用できます。コンストラクタを呼び出して基本クラスを呼び出します。 –

+0

ああ、 'construct'はコンストラクタではなく、メンバ関数テンプレートです。 – fredoverflow

1

ああ、constructorはコンストラクタではなく、メンバー関数テンプレートです。

おそらくセマンティクスが異なります。オリジナルのオーバーロードセットは、左辺値参照または右辺値参照のどちらかをconstに渡します。テンプレートバージョンは、左値参照を -constに渡すこともできます。 (私はCONSTへの右辺値参照を無視しています。)

すべてのしやすでconstructはどちらかであるU&&を受け入れることを宣言した(他のTを移動し、あなたの前の過負荷が動作しないでしょう)、この場合、が非で契約がすべきにもかかわらず-const lvalues、またはU const&を受け入れると宣言されており、この場合は無害です。

0

あなたは、少なくともconstruct(const T& x)、おそらく定義されconstruct(T&& x)の追加を持っている、とタイプUのあなたのオブジェクトのタイプTのオブジェクトに変換可能であると仮定すると、私はあなたが問題ないはずだと思う...

  1. 定数construct(const T& x)
  2. にタイプU意志の一時的なR値を結合するタイプUのL値基準は、construct(const T& x)
  3. にタイプUの非定数L値基準を結合しますconstruct(T&& x)又はconstruct(const T& x)に結合し、R値の基準バージョンを
  4. タイプUの定数r値の基準を定義されていない場合は、construct(const T& x)
関連する問題