5

クラスに次のような特別なメンバー関数がある場合は、テンプレートを特殊化しようとします(別の例でここにあります)。

template <typename T>
class has_begin
{
    typedef char one;
    typedef long two;

    template <typename C> static one test( decltype( &C::AnyFunc) ) ;
    template <typename C> static two test(...);

public:
    enum { value = sizeof(test<T>(0)) == sizeof(char) };
    enum { Yes = sizeof(has_begin<T>::test<T>(0)) == 1 };
    enum { No = !Yes };
};

AnyFuncこれは、過負荷になるまでうまく機能します。

class B : public vector<int>
{
public:
    void AnyFunc() const;
    void AnyFunc();
};

テンプレートから「はい」を取得するようにテストコードを書き直すにはどうすればよいですか?

4

2 に答える 2

2

引数なしのオーバーロードされた関数名(13.4p1)の使用は、単一のオーバーロード(13.4p4)に解決する必要があります。そうしないと、置換エラーが発生します。

メンバー関数の存在をテストしている場合は、それを呼び出す予定の引数を知っておく必要があります。

    template <typename C> static one test(
        typename std::add_pointer<decltype(std::declval<C>().AnyFunc())>::type);

一般に、次のような可変個引数テンプレートとパターンを使用できますresult_of

    template <typename C, typename... Args> static one test(
        typename std::add_pointer<decltype(
            std::declval<C>(std::declval<Args>()...).AnyFunc())>::type);

を使用add_pointerすると、これを関数の引数型として許可されていない関数の戻り型で機能させることができます(例void)。

于 2012-11-12T14:10:37.697 に答える
1

動作するバージョンが見つかりました:

    template <typename C> static one test( decltype(((C*)0)->AnyFunc())* ) ;

オブジェクトにconst関数があることを確認する場合は、次を使用します。

    template <typename C> static one test( decltype(((const C*)0)->AnyFunc())* ) ;

このバージョンでは、引数付きの関数は検出されません。

class B : public std::vector<int>
{
public:
    //void AnyFunc() const;
    //void AnyFunc();
    int AnyFunc(int);
};
于 2012-11-12T11:37:21.370 に答える