3

独自のスマート ポインター (C++ 11) とスタックを作成しようとしていますが、次の例で説明できる 1 つの問題があります。

#include <iostream>

template<typename T_Type>
class TestTemplateClass {
private:
    T_Type _state;

public:
    TestTemplateClass() : _state() {
        std::cout << "Default constructor" << std::endl;
    }

    TestTemplateClass(int inState) : _state(inState) {
        std::cout << "State constructor" << std::endl;
    }

    template<typename T_OtherType>
    TestTemplateClass(const TestTemplateClass<T_OtherType> &inValue) {
        std::cout << "Template-copy constructor" << std::endl;
    }

    template<typename T_OtherType>
    void operator = (const TestTemplateClass<T_OtherType> &inValue) {
        std::cout << "Operator" << std::endl;
    }

    ~TestTemplateClass() {
        std::cout << "Destructor" << std::endl;
    }
};

TestTemplateClass<int> createFunction() {
    return TestTemplateClass<int>();
}

int main() {
    TestTemplateClass<int> theReference = createFunction();
    std::cout << "Finished" << std::endl;
    return 0;
}

出力:

Default constructor
Destructor
Destructor
Finished
Destructor

ご覧のとおり、ここには非常に多くのデストラクタがあります。私の考えでは、copy elision と template-constructor の間の相互作用に何らかの問題がありますが、そのようなバグの理由が何であるかはわかりません。copy-constructorを追加して問題を修正し、explicitコンパイラに template-constructor を強制的に使用させようとしました。

// After TestTemplateClass(int inState), but it's not important
explicit TestTemplateClass(const OwnType &inValue) {
    std::cout << "Copy constructor" << std::endl;
}

次の出力を得ました:

Default constructor
Template-copy constructor
Destructor
Template-copy constructor
Destructor
Finished
Destructor

ここではすべて問題ないように見えますが、クリーンなソリューションには見えません。より良い代替手段はありますか?

4

2 に答える 2

5

(N)RVOでは、コンストラクター呼び出しとデストラクター呼び出しの数に矛盾が生じることはありません。それを原則的に不可能にするように設計されています。

問題はあなたのコードにあります。言語の規則に従って、コンストラクター テンプレートを使用してコピー コンストラクターを生成することはありません。コピー コンストラクターは決してテンプレートではありません。

したがって、クラス テンプレートは実際にはコピー コンストラクターを宣言していないため、コンパイラーはデフォルトのコンストラクターを生成します (もちろん何も出力しません)。コピー コンストラクターで特別な処理が必要な場合は、常に手動で宣言する必要があります。テンプレートをインスタンス化するために使用されることはありません。

于 2015-03-12T08:00:01.357 に答える