如何防止未实现方法的对象的模板生成 [英] How Can I Prevent Template Generation for Objects That Don't Implement a Method

查看:71
本文介绍了如何防止未实现方法的对象的模板生成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,出于示例目的,假设我有3个简单的struct,其中第二个不包含bar方法:

So for the purpose of example let's say I have 3 simple structs, the second of which doesn't contain a bar method:

struct one {
    void foo(const int);
    void bar();
};

struct two {
    void foo(const int);
};

struct three {
    void foo(const int);
    void bar();
};

然后我有一个struct,它将管理以下类型的对象:

Then I have a struct which will manage objects of these types:

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, [&](auto& value) { value.bar(); } ); }
};

当我尝试编译它时,我得到:

When I try to compile this I get:

错误:struct two没有名为bar

有没有办法解决这个问题?

Is there a way that I can work around this?

在线示例

推荐答案

首先是实用程序.一个是我们最喜欢的overload,它展示了三个C ++ 17功能,并且重载了多个函数对象的operator(),它们全部显示在两行中.

First, the utilities. One is our favorite overload that shows off three C++17 features, and overloads the operator() of several function objects, all in two lines.

template<class... Ts> struct overload : Ts... { using Ts::operator()...; };
template<class... Ts> overload(Ts...) -> overload<Ts...>;

然后接受所有后备标记类型:

Then an accepts-everything fallback tag type:

struct fallback_t { template<class T> fallback_t(T&&) {} };

现在通话本身.通过将value.bar()调用置于尾随返回类型中,然后使用后备重载对其进行重载,从而使原始通用lambda对SFINAE友好,如果实际调用该重载将具有未定义的行为(因为OP忽略[ted]任何行为的明确定义") ):

Now to the call itself. We make the original generic lambda SFINAE-friendly by putting the value.bar() call into the trailing return type, then overload it with a fallback overload that has undefined behavior if actually invoked (since OP "omit[ted] any explicit definition of behavior"):

void bar(const int key) { 
    findObject(key, overload {
          [&](auto& value) -> decltype(void(value.bar())) { value.bar(); },
          [](fallback_t){ fire_missiles_and_impregnate_cat(); }
    } ); 
}

这篇关于如何防止未实现方法的对象的模板生成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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