代码之家  ›  专栏  ›  技术社区  ›  Jonathan Mee

使用不同的返回类型强制SFINAE

  •  0
  • Jonathan Mee  · 技术社区  · 8 年前

    所以 this answer 演示如何使用返回类型中的函数强制 Substitution Failure is not an Error (SFINAE) .

    有什么办法可以用这个吗 是否具有与函数不同的返回类型?

    所以一个参数将此列为 overload 将触发SFINAE:

    overload {
        [&](auto& value) -> decltype(void(value.bar())) { value.bar(); } ,
        [](fallback_t) { cout << "fallback\n"; }
    }
    

    但假设我需要一个不同的返回类型,我如何仍然触发SFINAE?例如,我想这样做:

    overload {
        [&](auto& value) -> decltype(void(value.bar()), float) { value.bar(); return 1.0F; } ,
        [](fallback_t) { cout << "fallback\n"; return 13.0F; }
    }
    


    最小、完整、可验证的示例。要阅读的内容很多,但如果您不想查看该链接,在我尝试添加返回类型之前,会用到以下代码:

    struct one {
        void foo(const int);
        void bar();
    };
    
    struct two {
        void foo(const int);
    };
    
    struct three {
        void foo(const int);
        void bar();
    };
    
    template<class... Ts> struct overload : Ts... { using Ts::operator()...; };
    template<class... Ts> overload(Ts...) -> overload<Ts...>;
    struct fallback_t { template<class T> fallback_t(T&&) {} };
    
    struct owner {
        map<int, one> ones;
        map<int, two> twos;
        map<int, three> threes;
    
        template <typename T, typename Func>
        void callFunc(T& param, const Func& func) {
            func(param);
        }
    
        template <typename T>
        void findObject(int key, const T& func) {
            if(ones.count(key) != 0U) {
                callFunc(ones[key], func);
            } else if(twos.count(key) != 0U) {
                callFunc(twos[key], func);
            } else {
                callFunc(threes[key], func);
            }
        }
    
        void foo(const int key, const int param) { findObject(key, [&](auto& value) { value.foo(param); } ); }
        void bar(const int key) {
            findObject(key, overload {
                [&](auto& value) -> decltype(void(value.bar())) { value.bar(); } ,
                [](fallback_t) { cout << "fallback\n"; }
            } );
        }
    };
    
    int main() {
        owner myOwner;
    
        myOwner.ones.insert(make_pair(0, one()));
        myOwner.twos.insert(make_pair(1, two()));
        myOwner.threes.insert(make_pair(2, three()));
    
        myOwner.foo(2, 1);
        cout << myOwner.bar(1) << endl;
        cout << myOwner.bar(2) << endl;
        cout << myOwner.foo(0, 10) << endl;
    }
    
    1 回复  |  直到 8 年前
        1
  •  1
  •   bipll    8 年前

    你想要你的

    [&](auto& value) -> decltype(void(value.bar())) { value.bar(); } ,
    

    返回float而不是void?那么为什么不在decltype中添加float呢?

    [&](auto& value) -> decltype(void(value.bar()), 1.0f) { value.bar(); return 1.0; }