强制SFINAE使用不同的返回类型 [英] Forcing SFINAE With a Different Return Type

查看:44
本文介绍了强制SFINAE使用不同的返回类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此此答案演示了如何使用返回类型中的函数来强制

So this answer demonstrates how I can use a function in the return type to force Substitution Failure is not an Error (SFINAE).

有没有一种方法可以使用此并且具有与函数不同的返回类型?

Is there a way that I can use this and have a different return type from the function?

因此,向 overload 发送的自变量行将触发SFINAE:

So a arguments line this to overload will trigger the SFINAE:

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

但是可以说我需要一个不同的返回类型,如何仍然触发SFINAE?例如,我想做这样的事情:

But lets say that I need a different return type, how can I still trigger SFINAE? For example I'd like to do something like this:

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

是最小,完整,可验证的示例.有很多东西要阅读,但是如果您不想去检查链接,这是在我尝试添加返回类型之前涉及的代码:

This is the minimal, complete, verifiable example. It's a lot to read but if you don't want to go check out the link, this is the code that's involved before I try to add the return type:

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;
}

推荐答案

您要

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

返回浮点数而不是空值?那么为什么不将float添加到decltype?

to return float rather than void? Then why not add float to the decltype?

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

这篇关于强制SFINAE使用不同的返回类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆