0

スマート ポインター クラスを作成します。ベクトルに渡すと、コンパイル時にエラーメッセージが表示されます。しかし、明示的な宣言を削除すると、機能します。エラーは何ですか?

explicit shared_ptr(const shared_ptr<T>& sp)

の呼び出しに一致する関数がありませんshared_ptr<int>::shared_ptr(const shared_ptr<int> &)

 #include <iostream>
    #include <vector>
    using namespace std;




    template<class T>
    class shared_ptr {
    private:
      struct ptr {
        T* ptr;
        size_t count;
        void release() {
          if(-- count == 0) {
            delete ptr;
            delete this;
          }
        }
      };
    private:
      ptr* _ptr;
    public:
      explicit shared_ptr(T* p):
        _ptr(new ptr) {
        _ptr->ptr = p;
        _ptr->count = 1;
      }
      explicit shared_ptr(const shared_ptr<T>& sp):
      //explicit shared_ptr(const shared_ptr& sp):
        _ptr(sp._ptr) {
        ++ _ptr->count;
      }
      shared_ptr<T>& operator=(const shared_ptr<T>& sp) {
        _ptr->release();
        _ptr = sp._ptr;
        ++ _ptr->count;
        return *this;
      }

      shared_ptr<T>& operator=(T* p) {
        _ptr->release();
        _ptr = new ptr;
        _ptr->count = 1;
        _ptr->ptr = p;
      }

      T* get() {
           return _ptr->ptr;
      }

      T& operator*() {
        return *(_ptr->ptr);
      }

      T* operator->() {
          return _ptr->ptr;
      }


      ~shared_ptr() {
        _ptr->release();
      }


    };



    int main() {
        vector<shared_ptr<int> > vec;
        vec.push_back(shared_ptr<int>(new int(10)));
    }
4

1 に答える 1

1

として宣言されたコンストラクターは、明示的に呼び出すexplicit場合にのみ使用できます。この行で:

vec.push_back(shared_ptr<int>(new int(10)));

標準ライブラリのC++03実装で、最終的にvecベクターコピーされ、次のようなコピー初期化が行われるを渡します。

_Tp __x_copy = __x;

ここでのコピーコンストラクターの呼び出しは暗黙的ですが、コンストラクターはとしてマークされていexplicitます。したがって、エラー。

エラーはC++03コンパイラでのみ-std=c++03発生するか、フラグを使用してコンパイルするときにのみ発生することに注意してください。C++ 11ではpush_back()、右辺値引数を使用して関数を呼び出すと(インスタンス化する一時的なものなど)、コピーコンストラクターへの明示的な呼び出しで適切な値。

したがって、C++03コンパイラを使用していると思います。

通常、explicitコンストラクターは、厄介な暗黙の変換を回避するために、1つの引数を取るコンストラクターであり、コピーコンストラクターではありません(実際、C ++ 11ではexplicitコピーの初期化により、複数の引数を取るコンストラクターにも意味があります。ブレース付き初期化子リスト)。

コピーコンストラクタは通常、として宣言されていませんexplicit

于 2013-03-09T12:43:04.737 に答える