1

私はC ++を初めて使用し、現在テンプレートをいじって、それらをよりよく理解しています。これが私が試してきたことです:

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

template <typename T>
class someContainer
{
private:
    T val1;
    T val2;
public:
    someContainer(const T& in1, const T& in2)
        :val1(in1), val2(in2) {}

    template <template <typename Ty> class Comp>
    void sort()
    {
        bool result = Comp<T>()(val1, val2);
        cout << result << endl;

        return;
    }
};

template <typename R>
class Compare
{
public:
    bool operator () (const R& a, const R& b)
    {
        return a>b;
    }

};


int main()
{
    someContainer<int> myCont(7,6);
    myCont.sort<Compare>();


    cin.ignore();
    return 0;
}

私はほとんど同じことをしたいのですが、今回は関数です。基本的に次のようなもの:

myCont.sort<function>();

念のために言っておきますが、私はこれを望んでいません:

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

template <typename T>
class someContainer
{
private:
    T val1;
    T val2;
public:
    someContainer(const T& in1, const T& in2)
        :val1(in1), val2(in2) {}

    template <class Func>
    void sort(Func func)
    {
        bool result = func(val1,val2);
        cout << result << endl;

        return;
    }
};

//Try for sort functor

template <typename R>
bool compare(const R& a, const R& b)
{
    return a>b;
}


int main()
{
    someContainer<int> myCont(7,6);
    myCont.sort(compare<int>);


    cin.ignore();
    return 0;
}

/編集:私は正確に明確ではないかもしれないことに気づきました. 電話をかけたいのですがmyCont.sort<function>可能ですか?関数はあなたがクラスと呼ぶものではないことを認識していますが、汎用関数を sort() に渡すことは可能です:

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

template <typename T>
class someContainer
{
private:
    T val1;
    T val2;
public:
    someContainer(const T& in1, const T& in2)
        :val1(in1), val2(in2) {}

    template <typename Ty>
    void sort(bool (*_comp)(const Ty&, const Ty&))
    {
        cout << "Comp is of type: " << typeid(_comp).name() << endl;
        cout << _comp(val1, val2) << endl;
        return;
    }
};

template <typename R>
bool compare(const R& a, const R& b)
{
    return a>b;
}

int main()
{
    someContainer<int> myCont(7,6);
    myCont.sort(compare<int>); 


    cin.ignore();
    return 0;
}

戻り値の型をカスタマイズすることもできます:

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

template <typename T>
class someContainer
{
private:
    T val1;
    T val2;
public:
    someContainer(const T& in1, const T& in2)
        :val1(in1), val2(in2) {}

    template <typename Ret, typename Ty>
    void sort(Ret (*_comp)(const Ty&, const Ty&))
    {
        cout << "Comp is of type: " << typeid(_comp).name() << endl;
        cout << _comp(val1, val2) << endl;
        return;
    }
};

template <typename Ret, typename R>
Ret compare(const R& a, const R& b)
{
    return a>b;
}

int main()
{
    someContainer<int> myCont(7,6);
    myCont.sort(compare<bool,int>); 


    cin.ignore();
    return 0;
}

しかし、それは問題ではありません。できる限り最善の方法で説明していないことは承知していますので、何か追加したい場合は、何を教えてください. 私の考えは、次のようなことができるようにしたいということです: myCont.sort(); または myCont.sort(function);

質問の要点: 関数テンプレートを引数として別の関数のテンプレートに渡す方法はありますか? クラス テンプレートを引数として別の関数のテンプレートに渡したように:

myCont.sort<Compare>(); // Compare is a template - not a template specialization
//later in sort we got Comp<T>()()

compare という関数テンプレートを取得した場合、次のいずれかを行う方法があります。

myCont.sort<compare>();
myCont.sort(compare);

比較の特殊化ではなく、関数テンプレートを渡したいのですが、これはファンクタでできるので、関数でできないかな。私はしたくない:

myCont.sort(compare<some_type>);

関数テンプレートを取得し、それを sort() 内で特殊化したいと考えています。

前もって感謝します!

PS: コメントは小さなサイズしかないように見えるので、別の質問があります:myCont.sort(compare)このコードで this( ) が可能だったと思いますか (C++ に関数テンプレート パラメーターのデフォルト値があった場合)?

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

template <typename T>
class someContainer
{
private:
    T val1;
    T val2;
public:
    someContainer(const T& in1, const T& in2)
        :val1(in1), val2(in2) {}

    template <typename Ret = bool ,typename Ty = T>
    void sort(Ret (*_comp)(const T&, const T&))
    {
        cout << "Comp is of type: " << typeid(_comp).name() << endl;
        cout << _comp(val1, val2) << endl;
        return;
    }
};

template <typename Ret, typename R>
Ret compare(const R& a, const R& b)
{
    return a>b;
}

int main()
{
    someContainer<int> myCont(7,6);
    myCont.sort(compare); 

    cin.ignore();
    return 0;
}

PS

ところで、すべては、なぜこれをコンパイルできないのか疑問に思ったことから始まりました (明らかに someFunc が欠落しているためですが、リストが特殊化されている型から list.sort が someFunc の型を推測できることは論理的です):

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

template <typename T>
void display(const T& input)
{
    for(auto i = input.cbegin(); i!=input.cend(); ++i)
        cout << *i << ' ';
    cout << endl;
    return;
}

template <typename R>
bool someFunc(const R& in1, const R& in2)
{
    return in1>in2;
}

int main()
{
    list<int> myList;
    myList.push_back(5);
    myList.push_back(137);
    myList.push_back(-77);
    display(myList);

    myList.sort(someFunc); //change it to myList.sort(someFunc<int>) and it works
    //however I believe the compiler should be able to infer the type of someFunc from
    //the type of myList - I guess the STL just wasn't written for having template 
    //functions as a binary predicate
    display(myList);

    cin.ignore();
    return 0;

};
4

1 に答える 1

5

C++ には、オーバーロードされた関数または関数テンプレートのグループを表す型はありません。関数のグループを渡す唯一の方法は、関数を含むクラスとして渡すことです。

単一の関数 (おそらくテンプレート関数インスタンス) を渡したい場合は、関数ポインター (または参照) をテンプレート引数として使用できます。ただし、関数の型を推測することはできません。テンプレート引数の正式な型と正確に一致する必要があります。また、通常のパラメーターの代わりにテンプレート引数として渡すことにはほとんど価値がありません。パラメーターが定数の場合、インライン化中に、優れたコンパイラーは関数ポインターを直接呼び出しに最適化し、それもインライン化します。


編集への応答:

myCont.sort(compare) 動作します。テンプレート引数を作成し、それを使用しないという、コードで小さな間違いを犯しただけTyです。未使用の引数は推測できません。見る


ちなみにこれの代わりに

template <typename R>
class Compare
{
public:
    bool operator () (const R& a, const R& b)
    {
        return a>b;
    }

};

よろしければ

class Compare
{
public:
    template <typename R>
    bool operator () (const R& a, const R& b)
    {
        return a>b;
    }

};

operator()テンプレートを自動的に生成する新しい C++14 ラムダ。

于 2013-06-03T14:46:06.360 に答える