如何使用std :: shared_ptr <void>和另一种类型的std :: shared_ptr进行函数重载?

Almosnow

试用以下代码:

#include <functional>
#include <memory>

class C {
    public:
    void F(std::function<void(std::shared_ptr<void>)>){}
    void F(std::function<void(std::shared_ptr<int>)>){}
};

int main(){
    C c;
    c.F([](std::shared_ptr<void>) {});
}

您会看到一个编译错误:

prog.cc:12:7: error: call to member function 'F' is ambiguous
    c.F([](std::shared_ptr<void>) {});
    ~~^
prog.cc:6:10: note: candidate function
    void F(std::function<void(std::shared_ptr<void>)>){}
         ^
prog.cc:7:10: note: candidate function
    void F(std::function<void(std::shared_ptr<int>)>){}
         ^

有什么办法可以解决这种歧义?也许与SFINAE合作?

最高66

我很困惑,但我尝试解释一下。

我看你的拉姆达可以通过双方所接受std::function<void(std::shared_ptr<void>)>std::function<void(std::shared_ptr<int>)>; 您可以验证以下两行均已编译

std::function<void(std::shared_ptr<void>)>  f0 = [](std::shared_ptr<void>){};
std::function<void(std::shared_ptr<int>)>   f1 = [](std::shared_ptr<void>){};

这是因为(我想)共享指针int可以转换为共享指针void您可以验证以下行是否已编译

std::shared_ptr<void> sv = std::shared_ptr<int>{};

至此,我们可以看到

c.F([](std::shared_ptr<void>) {});

你不会传递std::function<void(std::shared_ptr<void>)>F(); 您正在传递可以同时转换为std::function<void(std::shared_ptr<void>)>的对象std::function<void(std::shared_ptr<int>)>因此可以用来调用的两个版本的对象F()

所以模棱两可。

有什么办法可以解决这种歧义?也许与SFINAE合作?

也许与标签调度。

您可以添加未使用的参数和模板 F()

void F (std::function<void(std::shared_ptr<void>)>, int)
 { std::cout << "void version" << std::endl; }

void F (std::function<void(std::shared_ptr<int>)>, long)
 { std::cout << "int version" << std::endl; }

template <typename T>
void F (T && t)
 { F(std::forward<T>(t), 0); }

这样打电话

c.F([](std::shared_ptr<void>) {});
c.F([](std::shared_ptr<int>){});

您可以从第一个调用中获得“无效版本”(两个非模板都F()匹配,但首选“无效版本”,因为0它是int),而从第二个调用中获得F()“ int版本” (仅匹配“ int版本”)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章