C++ STL 101:重载函数导致构建错误

发布于 2024-08-31 06:02:12 字数 981 浏览 1 评论 0原文

如果我不重载 myfunc,那么简单的代码就可以工作。

void myfunc(int i)
{
    std::cout << "calling myfunc with arg " << i << std::endl;
}
void myfunc(std::string s)
{
    std::cout << "calling myfunc with arg " << s << std::endl;
}
void testalgos()
{
    std::vector<int> v;
    v.push_back(1);
    v.push_back(2);

    std::vector<std::string> s;
    s.push_back("one");
    s.push_back("two");

    std::for_each( v.begin(), v.end(), myfunc);
    std::for_each( s.begin(), s.end(), myfunc);
    return;
}

int _tmain(int argc, _TCHAR* argv[])
{
    std::cout << "Hello World" << std::endl;
    testalgos();
    return 0;
}

两个 for_each 调用都会重复出现以下构建错误。

错误 C2914:“std::for_each”:无法推断模板参数,因为函数参数不明确 错误 C2784:“_Fn1 std::for_each(_InIt,_InIt,_Fn1)”:无法从“std::_Vector_iterator<_Ty,_Alloc>”推导出“_InIt”的模板参数。

如果我不重载 myfunc,它确实有效。有人可以解释一下这里发生了什么吗?

TIA

Trivial code that works if I do not overload myfunc.

void myfunc(int i)
{
    std::cout << "calling myfunc with arg " << i << std::endl;
}
void myfunc(std::string s)
{
    std::cout << "calling myfunc with arg " << s << std::endl;
}
void testalgos()
{
    std::vector<int> v;
    v.push_back(1);
    v.push_back(2);

    std::vector<std::string> s;
    s.push_back("one");
    s.push_back("two");

    std::for_each( v.begin(), v.end(), myfunc);
    std::for_each( s.begin(), s.end(), myfunc);
    return;
}

int _tmain(int argc, _TCHAR* argv[])
{
    std::cout << "Hello World" << std::endl;
    testalgos();
    return 0;
}

The following build errors repeat for both for_each calls.

error C2914: 'std::for_each' : cannot deduce template argument as function argument is ambiguous
error C2784: '_Fn1 std::for_each(_InIt,_InIt,_Fn1)' : could not deduce template argument for '_InIt' from 'std::_Vector_iterator<_Ty,_Alloc>'.

It does work if I do not overload myfunc.Can someone explain what is happening here.

TIA

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

九歌凝 2024-09-07 06:02:12

在这种情况下,编译器无法解析重载。 std::for_each() 期望其函子具有某种任意类型 F,而不是某种特定的函数类型,因此重载的 myFunc 在这里是不明确的。

您可以明确选择要使用的重载:

std::for_each( v.begin(), v.end(), (void (*)(int))myfunc);
std::for_each( s.begin(), s.end(), (void (*)(std::string))myfunc);

替代方案(最后两个来自评论)

typedef void (*IntFunc)(int);
std::for_each(/*...*/, (IntFunc)myfunc);

typedef void IntFunc(int);
std::for_each(/*...*/, static_cast<IntFunc*>(&myFunc));

// using identity (e.g. from boost or C++0x):
std::for_each(/*...*/, (identity<void(int)>::type*)myfunc);

In that context the overloads can't be resolved by the compiler. std::for_each() expects some arbitrary type F for its functor, not some specific function type, thus the overloaded myFunc is ambiguous here.

You can explicitly select which overload to use:

std::for_each( v.begin(), v.end(), (void (*)(int))myfunc);
std::for_each( s.begin(), s.end(), (void (*)(std::string))myfunc);

Alternatives (last two are from the comments):

typedef void (*IntFunc)(int);
std::for_each(/*...*/, (IntFunc)myfunc);

typedef void IntFunc(int);
std::for_each(/*...*/, static_cast<IntFunc*>(&myFunc));

// using identity (e.g. from boost or C++0x):
std::for_each(/*...*/, (identity<void(int)>::type*)myfunc);
沉溺在你眼里的海 2024-09-07 06:02:12

编译器无法推断函子的类型。您可以制作函数模板:

template<typename T> void myfunc(T);

template<> void myfunc(int i)
{
    std::cout << "calling myfunc with arg " << i << std::endl;
}
template<> void myfunc(std::string s)
{
    std::cout << "calling myfunc with arg " << s << std::endl;
}

然后按如下方式使用它:

std::for_each( v.begin(), v.end(), myfunc<int>);
std::for_each( s.begin(), s.end(), myfunc<std::string>);

Compiler cannot deduce type of functor. You could make your function template:

template<typename T> void myfunc(T);

template<> void myfunc(int i)
{
    std::cout << "calling myfunc with arg " << i << std::endl;
}
template<> void myfunc(std::string s)
{
    std::cout << "calling myfunc with arg " << s << std::endl;
}

Then use it as follows:

std::for_each( v.begin(), v.end(), myfunc<int>);
std::for_each( s.begin(), s.end(), myfunc<std::string>);
溺深海 2024-09-07 06:02:12

编译器无法推断出要使用哪个,因为两个重载都会同样匹配参数(它不以任何方式依赖于迭代器的类型)。

除了将参数显式转换为合适的指针类型之外,另一个选择可能是使用 std::ptr_fun 辅助函数将其包装在函子中,并通过给出(部分)来帮助模板推导明确地。

std::for_each( v.begin(), v.end(), std::ptr_fun<int>(myfunc));
std::for_each( s.begin(), s.end(), std::ptr_fun<std::string>(myfunc));

The compiler cannot deduce which to use, as both overloads would match the argument (which doesn't depend on the types of the iterator in any way) equally well.

Another option in addition to explicitly casting the argument to suitable pointer type might be here to use the std::ptr_fun helper function to wrap it in a functor, and help the template deduction by giving (part of) it explicitly.

std::for_each( v.begin(), v.end(), std::ptr_fun<int>(myfunc));
std::for_each( s.begin(), s.end(), std::ptr_fun<std::string>(myfunc));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文