4

前回の質問からの続きです。私が持っているのは、次のような sfinae 依存チェーンを形成する一連の関数です (「A -> B」表記は、A の存在が B の存在に依存することを意味します):

S::f_base -> S::f -> ns::f_ -> f -> T::f

ここで、T はテンプレート引数です。次のように実装されています

#include <utility>

struct S;

template <typename T>
auto f(S& s, T const& t) -> decltype(t.f(s), void())
{
    t.f(s);
}

namespace ns
{
    template <typename T>
    auto f_(S& s, T const& t) -> decltype(f(s, t), void())
    {
        f(s, t);
    }
} 

struct S
{
    template <typename T>
    auto f(T const& t) -> decltype(ns::f_(std::declval<S&>(), t), void())
    {
        ns::f_(*this, t);
    }

    template <typename T>
    auto f_base(T const* t_ptr) -> decltype(f(*t_ptr), void())
    {
        f(*t_ptr);
    }
};

struct pass
{
   void f(S&) const
   {
   }
};

struct fail
{

};

int main()
{
    S s;
    s.f(pass()); // compiles
    //s.f(fail()); // doesn't compile
    return 0;
}

意図したとおりに動作します。次のようS::fに、クラス本体の定義とそのS::f_base外側に定義を移動しようとすると、問題が発生します。

#include <utility>

struct S;

template <typename T>
auto f(S& s, T const& t) -> decltype(t.f(s), void())
{
    t.f(s);
}

namespace ns
{
    template <typename T>
    auto f_(S& s, T const& t) -> decltype(f(s, t), void())
    {
        f(s, t);
    }
} 

struct S
{
    template <typename T>
    auto f(T const& t) -> decltype(ns::f_(std::declval<S&>(), t), void());

    template <typename T>
    auto f_base(T const* t_ptr) -> decltype(f(*t_ptr), void());
};

template <typename T>
auto S::f(T const& t) -> decltype(ns::f_(std::declval<S&>(), t), void())
{
    ns::f_(*this, t);
}

template <typename T>
auto S::f_base(T const* t_ptr) -> decltype(f(*t_ptr), void()) // <---- HERE ---
{
    f(*t_ptr);
}

int main()
{

    return 0;
}

矢印でマークされた行では、GCC 4.7.1不満を表しています。

エラー: 'decltype ((((S*)0)->S::f((* t_ptr)), void())) S::f_base(const T*)' のプロトタイプは、クラス内のいずれとも一致しません ' S'
エラー: 候補は: template decltype ((((S*)this)->S::f((* t_ptr)), void())) S::f_base(const T*)

(宣言と定義の両方で) を先頭に追加してf、使用しているものを明示的に指定しようとしましたが、エラーは解決しません。f_basestd::declval<S&>().

次のように依存関係グラフを変更できることはわかっています。

S::f_base ->
          -> ns::f_ -> f -> T::f
S::f      ->

と一緒にS::f_base依存するようにしますが、最初の依存グラフでこれを行う方法はありますか?ns::f_S::f

4

1 に答える 1