[英]How to solve function overloading ambiguity in following code
Suppose there are function ovelaods for int
and double
. 假设有函数ovelaods用于
int
和double
。
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);
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.