Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在类主体外部定义的成员函数上的sfinae_C++_Templates_C++11_Sfinae_Decltype - Fatal编程技术网

C++ 在类主体外部定义的成员函数上的sfinae

C++ 在类主体外部定义的成员函数上的sfinae,c++,templates,c++11,sfinae,decltype,C++,Templates,C++11,Sfinae,Decltype,有点像是我父亲的延续。我得到的是一组函数,它们形成了一个sfinae依赖链,就像这样(让“a->B”符号表示a的存在依赖于B的存在): 其中T是模板参数。它的实现方式如下: 在标有箭头的行上,GCC 4.7.1表示不满: 错误:“decltype(((S*)0)->S::f((*t_ptr)),void())S::f_base(const t*)”的原型与类中的任何原型都不匹配 错误:候选项是:模板decltype(((S*)this)->S::f((*t_ptr)),void())S::f_b

有点像是我父亲的延续。我得到的是一组函数,它们形成了一个sfinae依赖链,就像这样(让“a->B”符号表示a的存在依赖于B的存在):

其中T是模板参数。它的实现方式如下:

在标有箭头的行上,GCC 4.7.1表示不满:

错误:“decltype(((S*)0)->S::f((*t_ptr)),void())S::f_base(const t*)”的原型与类中的任何原型都不匹配
错误:候选项是:模板decltype(((S*)this)->S::f((*t_ptr)),void())S::f_base(const t*)

我试图通过在
std::declval()前面加上
std::declval(),
来明确指定我在
f_base
中使用的
f
,但错误仍然存在

我知道我可以这样修改依赖关系图:

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

要使
S::f_base
S::f
一起依赖于
S::f
,但有没有办法用第一个依赖关系图来实现这一点?

GCC 4.X不是元编程的最佳选择

我已设法使其在4.7.3()中编译:

#包括
结构;
模板
自动f(S&S,T const&T)->decltype(T.f(S),void())
{
t、 f(s);
}
名称空间ns
{
模板
自动f(S&S,T const&T)->decltype(f(S,T),void())
{
f(s,t);
}
} 
//一些std::void\u不喜欢但与GCC4.x兼容
模板
结构无效\u t
{
使用type=typename std::enable_if::type;
};
结构
{
模板
auto f(T const&T)->decltype(ns::f_(std::declval(),T),void());
模板
auto f_base(T const*T_ptr)->typename void_T:type;
};
模板
自动S::f(T const&T)->decltype(ns::f_40; std::declval(),T),void())
{
ns::f_uz(*此,t);
}
//::f是必需的,如果只是“f”,则失败
模板
自动S::f_base(T const*T_ptr)->typename void_T::type
{
f(*t_ptr);
}
int main()
{
返回0;
}
注意:

在GCC4.X中,我看到了一些奇怪的东西,比如:

template<class T>
struct void_t
{
   using type = void;
};
模板
结构无效\u t
{
使用类型=无效;
};

其中,GCC将
void\u t::type
替换为
void
,即使
expr
无效。这就是为什么我使用这个
void\u t

的实现,一个明显的问题:为什么要将定义移到类主体之外?@Xeo将接口和实现分开,至少在视觉上是这样,因为这些函数实际上比这里简化的一行程序大得多。第二个代码在Windows上与Clang r161057和GCC 4.6.3的libstdc++一起工作。似乎是GCC的一个bug,因为Clang编译很好(根据)。因为声明是完全相同的,所以不会想到其他任何事情。也使用VS2012编译。
#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;
}
S::f_base ->
          -> ns::f_ -> f -> T::f
S::f      ->
#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);
    }
} 

// some std::void_t like but GCC4.x compatible
template<class T>
struct void_t
{
   using type = typename std::enable_if<std::is_same<T,T>::value >::type;
};

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) ->  typename void_t< decltype (::f(*std::declval<T const*>()))>::type ;
};


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

// ::f is needed, fail if just 'f'
template <typename T>
auto S::f_base(T const* t_ptr) ->  typename void_t< decltype (::f(*std::declval<T const*>()))>::type
{
    f(*t_ptr);
}
int main()
{

    return 0;
}
template<class T>
struct void_t
{
   using type = void;
};