简体   繁体   English

如何在以下代码中解决函数重载歧义

[英]How to solve function overloading ambiguity in following code

Suppose there are function ovelaods for int and double . 假设有函数ovelaods用于intdouble

void Print(int v)
{
    cout << v << endl;
}

void Print(double v)
{
    cout << v << endl;
}

There is function wich is intended to pass in as callable one of above functions. 旨在将上述功能之一称为可传递功能。

template<typename FnT>
void Function(int v, FnT&& fn)
{
    fn(v);
}

But following code is ambiguous: 但是下面的代码是模棱两可的:

Function(1, Print);

Live example 现场例子

Compiller fails to deduce type for second argument. 编译器无法推断第二个参数的类型。 This can be easily solved: 这很容易解决:

Function(1, static_cast<void(*)(int)>(Print));

I believe exists more generic and elegant way to solve the issue. 相信存在解决问题的更通用,更优雅的方法。 The issue can be raised up in STL algorithm, when function overload is added. 添加函数重载后,可以在STL算法中提出该问题。

vector<int> v = { 1,2,3 };
for_each(v.begin(), v.end(), Print); // ambigous code

How to solve this in pretty way? 如何以漂亮的方式解决这个问题?

Wrap it in a function object: 将其包装在一个函数对象中:

#include <iostream>
#include <utility>

void Print(int v)
{
    std::cout << v << std::endl;
}

void Print(double v)
{
    std::cout << v << std::endl;
}

template<typename FnT>
void Function(int v, FnT&& fn)
{
    fn(v);
}

auto print_wrapper() {
    return [](auto&&...args) -> decltype(auto)
    {
        return Print(std::forward<decltype(args)>(args)...);
    };
}

int main()
{
    Function(1, print_wrapper());
}

On a more theoretical note, what we're doing here is using a bandage to fix a broken design. 从理论上讲,我们在这里正在使用绷带修复损坏的设计。

A better design would be to define the concept of Print as a template function object. 更好的设计是将“ Print的概念定义为模板功能对象。 Then we can specialise it and customise it to our heart's content. 然后,我们可以对其进行专门化,并根据我们的内心需求对其进行自定义。

A (very complete) model of this is boost::hash<> which is worth half a day of anyone's time as a study exercise. 一个(非常完整的)模型是boost::hash<> ,它值得任何人半天的学习时间。

A simple example: 一个简单的例子:

#include <iostream>
#include <utility>
#include <string>

struct Printer
{
    void operator()(const int& i) const {
        std::cout << i << std::endl;
    }

    void operator()(const double& i) const {
        std::cout << i << std::endl;
    }

    template<class Anything>
    void operator()(const Anything& i) const {
        custom_print(i);
    }
};

struct Foo
{

};
void custom_print(Foo const& f) 
{
    std::cout << "a Foo" << std::endl;
}

template<typename X, typename FnT>
void Function(X const& x, FnT&& fn)
{
    fn(x);
}

int main()
{
    Function(1, Printer());
    Function(1.0, Printer());
    Function(Foo(), Printer());
}

另外,您可以使用lambda:

Function(42, [](int i) {Print(i);});.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM