SFINAE decltype comma operator trick

后端 未结 1 1187
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-02-05 18:29

After reading Matthieu\'s answer here, I decided to try this myself.

My attempt fails to compile because SFINAE doesn\'t kick in and cull the has_foo functi

相关标签:
1条回答
  • 2021-02-05 19:06

    The primary issue here AFAICS is that you are using the run-time reference as a constexpr function parameter. Replacing this works just fine.

    #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, 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>(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;
    }
    
    0 讨论(0)
提交回复
热议问题