Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何解决下面代码中的函数重载歧义_C++_Templates_Stl_Overloading - Fatal编程技术网

C++ 如何解决下面代码中的函数重载歧义

C++ 如何解决下面代码中的函数重载歧义,c++,templates,stl,overloading,C++,Templates,Stl,Overloading,假设有用于int和double的函数OVELOADS void Print(int v) { cout << v << endl; } void Print(double v) { cout << v << endl; } 编译器无法推断第二个参数的类型。这很容易解决: Function(1, static_cast<void(*)(int)>(Print)); 功能(1,静态播放(打印)); 我相信有更通用和

假设有用于
int
double
的函数OVELOADS

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

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

编译器无法推断第二个参数的类型。这很容易解决:

Function(1, static_cast<void(*)(int)>(Print));
功能(1,静态播放(打印));
我相信有更通用和优雅的方式来解决这个问题。当添加函数重载时,STL算法中可能会出现此问题

vector<int> v = { 1,2,3 };
for_each(v.begin(), v.end(), Print); // ambigous code
向量v={1,2,3}; 对于每个(v.begin(),v.end(),Print);//歧义码
如何以漂亮的方式解决此问题?

将其包装在函数对象中:

#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());
}

将其包装在函数对象中:

#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());
}

或者,您可以使用lambda:

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

或者,您可以使用lambda:

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

我的意思是,你可以在这方面滥用模板,但在你的例子中,1)你不需要重载,2)代替
std::for_each
使用ranged for循环。这只是一个语法示例。当使用任何STL算法或任何带有可调用项的函数作为输入参数时,您可以在任何上下文中使用它。这是我的观点。。函数模板也会出现同样的问题。尽管使用了宏,维托里奥·罗密欧(Vittorio Romeo)的解决方案是通用而简洁的。它也适用于您的案例(事实上,它甚至使用相同的示例进行打印)。谢谢。有道理。我的意思是,你可以为此滥用模板,但在你的例子中,1)你不需要重载,2)代替
std::for_,使用ranged for循环。这只是一个语法示例。当使用任何STL算法或任何带有可调用项的函数作为输入参数时,您可以在任何上下文中使用它。这是我的观点。。函数模板也会出现同样的问题。尽管使用了宏,维托里奥·罗密欧(Vittorio Romeo)的解决方案是通用而简洁的。它也适用于您的案例(事实上,它甚至使用相同的示例进行打印)。谢谢。有道理。这对“打印”有用。但我认为OP需要一个更通用的解决方案。出于好奇问:有什么特别的理由使用参数包(
args
)而不是
print\u wrapper()
lambda中的单个参数(假设
print
目标是一个单参数函数)?或者只是为了通用性,以防扩展
Print
重载?谢谢!很好的
打印解决方案
。缺点是我应该为每个可能重载的函数编写这样的包装器。@Viktor诀窍是首先根据可变函子概念来考虑重载,然后提供重载以满足函子的概念。你所做的是说,“我有一袋零件——我怎样才能把它变成一个概念?”。一个更好的方法是创建一个概念,然后问“我需要哪些部分才能使这个概念起作用”。@StoryTeller如我对Viktor的评论所示。如果我们不得不这样做,设计就被破坏了。
Print
的概念应该是一个可以专门化的函子。这将适用于“Print”。但我认为OP需要一个更通用的解决方案。出于好奇问:有什么特别的理由使用参数包(
args
)而不是
print\u wrapper()
lambda中的单个参数(假设
print
目标是一个单参数函数)?或者只是为了通用性,以防扩展
Print
重载?谢谢!很好的
打印解决方案
。缺点是我应该为每个可能重载的函数编写这样的包装器。@Viktor诀窍是首先根据可变函子概念来考虑重载,然后提供重载以满足函子的概念。你所做的是说,“我有一袋零件——我怎样才能把它变成一个概念?”。一个更好的方法是创建一个概念,然后问“我需要哪些部分才能使这个概念起作用”。@StoryTeller如我对Viktor的评论所示。如果我们不得不这样做,设计就被破坏了。
Print
的概念应该是一个可以专门化的函子。
Function(42, [](int i) {Print(i);});.