当前位置: 首页 > 知识库问答 >
问题:

C++11风格的SFINAE和模板实例化中的函数可见性

乔俊才
2023-03-14
struct S;

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

struct S
{
    template <typename T>
    auto f(T const& t)
        -> decltype(f(*this, t), void())
    {
        f(*this, t); // <------------------------------------------- HERE
    }
};

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

struct fail
{
};

int main()
{
    S s;
    s.f(pass()); // should compile fine
    //s.f(fail()); // should fail to compile due to absence of f from S
    return 0;
}

作为@N.M。据说,成员函数完全隐藏自由函数,即使它们的签名不同,所以这里有一个解决方案,它不会破坏f的ADL(与@n.m建议的全名限定不同)。将free函数(f_dispatcher)设置在没有人会看到的地方(detail),并在s::f中完全限定其名称。在该函数中,调用freef,并让ADL从那里开始处理它,如下所示:

struct S;

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

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

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

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

struct fail
{
};

int main()
{
    S s;
    s.f(pass()); // compiles fine
    //s.f(fail()); // fails to compile due to absence of f from S
    return 0;
}

共有1个答案

茅星华
2023-03-14

这与SFINAE或模板或C++11或ADL无关。

成员隐藏所有具有相同名称的非成员,无论类型如何。如果有一个名为f的成员,则不能引用任何名为f的非成员,除非使用限定名(例如::f)。

只需使用::f(*this,t);

 类似资料:
  • 在C++11之前,类模板和函数模板只能含有固定数量的模板参数。C++11增强了模板功能,允许模板定义中包含0到任意个模板参数,这就是可变参数模板。可变参数模板的加入使得C++11的功能变得更加强大,而由此也带来了许多神奇的用法。 可变参数模板 可变参数模板和普通模板的语义是一样的,只是写法上稍有区别,声明可变参数模板时需要在typename或class后面带上省略号...: template<ty

  • 我有下面的代码,我希望TestEnableIf与不同的专门化有不同的打印功能,但它没有按计划工作,错误如下。 我不明白的是,sfinae应该意味着专门化失败不是错误,那么编译器为什么要抱怨失败?

  • 函数模板、成员函数模板、或类模板的成员函数或静态数据成员的专门化可以在翻译单元内具有多个实例化点,并且除了上述实例化点之外,对于在翻译单元内具有实例化点的任何这样的专门化,翻译单元的末尾也被认为是实例化点。类模板的专门化在翻译单元中最多有一个实例化点。任何模板的专门化都可能在多个翻译单元中具有实例化点。如果两个不同的实例化点根据一个定义规则赋予一个模板专门化不同的含义,则程序是格式不良的,不需要诊

  • 本文向大家介绍C++函数模板与类模板实例解析,包括了C++函数模板与类模板实例解析的使用技巧和注意事项,需要的朋友参考一下 本文针对C++函数模板与类模板进行了较为详尽的实例解析,有助于帮助读者加深对C++函数模板与类模板的理解。具体内容如下: 泛型编程(Generic Programming)是一种编程范式,通过将类型参数化来实现在同一份代码上操作多种数据类型,泛型是一般化并可重复使用的意思。泛

  • 考虑以下示例: 使用GCC 5.2编译会引发以下编译错误: 但是标准在14.6.5中说: 友元类或函数可以在类模板中声明。当模板被实例化时,其朋友的名称被视为在实例化点显式声明了专门化。 为什么编译失败?在GCC 3.4中,通过。

  • 对于将SFINAE与可变模板类一起使用,我似乎找不到一个好的解决方案。 假设我有一个不喜欢引用的可变参数模板对象: 以及一个类,可以方便地检查参数包是否包含引用: 我如何使用它来专门化NoRef的情况下,引用存在于arg包?