2

ジェネリックコーディングスタイルを使用して、制限されたコンセプトAPIをジェネリックスタックにラップしようとしています。私が遭遇している問題は、私のコンストラクターの1つ、テンプレート化されたスタックを取得する最も重要なコンストラクターが、私のコピーコンストラクターをオーバーライドしていることです。問題のクラス、いくつかのテストコード、およびコンパイラから取得したエラーの要点があります:https ://gist.github.com/biot023/5178831

作成したスタックで値セマンティクスを使用できるようにしたいのですが、スタックのベクトルに割り当てるだけで使用できます。ただし、これにより、コピーコンストラクタの問題が発生します。

コピーコンストラクターを明示的にトリガーする方法(テストコードで実際に実行する必要があるだけです)を教えてもらえますか、またはどこが間違っているのかを教えてもらえますか?

4

1 に答える 1

1

問題は、コンストラクターテンプレートがコピーコンストラクターよりもよく一致することです。

// Copy constructor
WrappedStack( const WrappedStack &other )

// Constructor template
template <typename S>
WrappedStack( S &stack )

タイプのオブジェクトWrappedStack<T>クラステンプレートパラメーターTは)でインスタンス化されると、コンストラクターテンプレートのインスタンス化された署名は次のようになります。

WrappedStack( WrappedStack<T> &stack )

constこれは、引数の型が修飾されていない場合、const変換を必要としないため、コピーコンストラクターよりも適切に一致します。したがって、コンストラクターテンプレートはオーバーロード解決によって選択され、その本体がインスタンス化されて、発生しているエラーが発生します。

必要に応じてコンパイラにコピーコンストラクタを使用させるには、SFINAEを使用して、型WrappedStack<T>または暗黙的にに変換可能な型のオブジェクトでコンストラクタテンプレートをインスタンス化するときに置換エラーを発生させることができますWrappedStack<T>。例えば:

#include <type_traits>

template<
    typename S,
    typename std::enable_if<
        !std::is_convertible<S, WrappedStack<T> const&>::value
        >::type* = nullptr>
WrappedStack( S &stack ) : __stack( new wrapped_stack_t<S, T>( stack ) ) {}

この正常にコンパイルされた実例を参照してください。

于 2013-03-16T23:55:32.090 に答える