1

3 つのコンストラクターを持つクラス テンプレートがあり、そのうちの 1 つは関数テンプレートです。

template<class T>
class TemplateOverLoading
{
public:
    TemplateOverLoading(void){};
    ~TemplateOverLoading(void){};
    //constructor that take reference
    TemplateOverLoading(std::string& qName, T& qValue )
        :   mName(qName),
            mValue( &qValue)
    {
        std::cout << "Reference -> "<< *mValue <<"\n";
    }

    //Template constructor that takes array
    template<class T, int N>
    TemplateOverLoading(std::string& qName, T (&t)[N])
        :   mName(qName),
            mValue(t)
    {
        std::cout << "Array ->\n";
        for(int i = 0; i < N; i++)
            std::cout<< mValue[i];
        std::cout << std::endl;
    }

    //Other constructor that take pointer
    TemplateOverLoading(std::string& qName, T* qValue )
        :   mName(qName),
            mValue( qValue)
    {
        std::cout << "Pointer "<< *mValue <<"\n";
    }
private:
    T*               mValue;
    //T*              mValueArray;
    std::string&    mName;
};

私のアプリケーションから、参照型/値、ポインター、および配列を区別し、特定の操作を実行する必要があります。したがって、別のコンストラクターを使用することにしました。

次の方法でコンストラクターを呼び出そうとしています。

int init(10);
int intArray[10] = {0,1,2,3,4,5,6,7,8,9};
TemplateOverLoading<int> mInt(std::string("mInt"), init);    
TemplateOverLoading<int> mIntArray( std::string("mIntArray"), intArray );

問題は、ポインターを持つコンストラクターが定義されている場合、配列コンストラクターが呼び出されないことです。ただし、それをコメントアウトすると、配列が適切に出力されます。

出力:

(when pointer constructor is present)
Reference -> 10
Pointer 0

(when pointer constructor is not present)
Reference -> 10
Array ->
0123456789

したがって、構文的には可能であり、配列サイズ N を正しく推測できます。

明らかに、配列コンストラクターが存在する場合、コンパイラーを混乱させています。したがって、コンパイラに自動的に推測させる代わりに、配列コンストラクターのテンプレートパラメーターを指定して、通常の関数とは異なり、テンプレートパラメーターを具体的に指定できないことを確認しようとしました。

オーバーロードを区別するために、配列コンストラクターにダミーパラメーターを導入することを考えましたが、うまくいきません。

これを解決する他の方法はありますか?手がかりをいただければ幸いです。

4

1 に答える 1

1

ポインター コンストラクターのパラメーターを にしT*& qValueます。

TemplateOverLoading(std::string& qName, T*& qValue )
    :   mName(qName),
        mValue( qValue)
{
    std::cout << "Pointer "<< *mValue <<"\n";
}

ポインターへの参照にすることで、配列からポインターへの減衰が防止され、配列コンストラクターが選択されます。

また、コードがどのようにコンパイルされるかわかりません。多くのエラーが表示されます。

テンプレート コンストラクターにはパラメーターがあり、これはクラス テンプレートの とclass T競合します。class T

template<class T, int N>
    TemplateOverLoading(std::string& qName, T (&t)[N])

class Tこれは、たとえばclass U次のように変更する必要があります。

template<class U, int N>
        TemplateOverLoading(std::string& qName, U (&t)[N])

コンストラクターは非 const左辺値参照も取ります。非 const 参照は、コンストラクター呼び出しで渡す一時変数にバインドできませんstd::string("mIntArray")。に変更するconst std::string&か、値で取得する必要があります。また、メンバーstd::string& mName;は参照であるため、そこを削除する必要が&あります。

于 2013-03-04T03:14:36.003 に答える