微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c – SFINAE decltype逗号操作符技巧

阅读Matthieu的答案 here后,我决定自己尝试一下.

我的尝试无法编译,因为SFINAE不会踢入并剔除尝试访问T :: foo的has_foo函数.

error: ‘struct Bar’ has no member named ‘foo’

我错过了什么,还是我试图以这种方式不可能?

(我使用gcc-4.7.2)

完整的例子如下:

#include <iostream>

// culled by SFINAE if foo does not exist
template<typename T>
constexpr auto has_foo(T& t) -> decltype((void)t.foo,bool())
{
    return true;
}
// catch-all fallback for items with no foo
constexpr bool has_foo(...)
{
    return false;
}
//-----------------------------------------------------

template<typename T,bool>
struct GetFoo
{
    static int value(T& t)
    {
        return t.foo;
    }
};
template<typename T>
struct GetFoo<T,false>
{
    static int value(T&)
    {
        return 0;
    }
};
//-----------------------------------------------------

template<typename T>
int get_foo(T& t)
{
    return GetFoo<T,has_foo(t)>::value(t);
}
//-----------------------------------------------------

struct Bar
{
    int val;
};

int main()
{
    Bar b { 5 };
    std::cout << get_foo(b) << std::endl;
    return 0;
}

解决方法

这里的主要问题是AFAICS是使用运行时引用作为constexpr函数参数.更换这个工作很好.
#include <iostream>

// culled by SFINAE if foo does not exist
template<typename T>
constexpr auto has_foo(int) -> decltype(std::declval<T>().foo,bool())
{
    return true;
}
// catch-all fallback for items with no foo
template<typename T> constexpr bool has_foo(...)
{
    return false;
}
//-----------------------------------------------------

template<typename T,has_foo<T>(0)>::value(t);
}
//-----------------------------------------------------

struct Bar
{
    int val;
};
struct Foo {
    int foo;
};

int main()
{
    Bar b { 5 };
    Foo f { 5 };
    std::cout << get_foo(b) << std::endl;
    std::cout << get_foo(f) << std::endl;
    return 0;
}

原文地址:https://www.jb51.cc/c/113465.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐