繁体   English   中英

将函数指针传递给函数时处理<unresolved overloaded function type>

[英]Dealing with <unresolved overloaded function type> when passing function pointer to function

我们考虑一下:

void goo () {
    std::cout << "void goo ()\n";
}   

int goo (int) {
    std::cout << "int goo (int)\n";
    return 42;
}

现在我想使用这样定义的包装函数调用其中一个函数:

template <typename F, typename... A>
void c (F&& f, A&&... a) {
    f (std::forward<A> (a)...);
}

用法:

c (&goo, 10); // (X)
c (&goo);     // (Y)

两种情况都失败了(GCC 5.3.1)并出现了适当的错误:

error: no matching function for call to ‘c(<unresolved overloaded function type>, int)’
error: no matching function for call to ‘c(<unresolved overloaded function type>)’

就我而言,失败是因为编译器在必须初始化f对象(信息太少)时无法选择适当的重载。

作为解决方案当然我可以编写这样的使用调用:

c (static_cast<int (*) (int)> (&goo), 10);
c (static_cast<void (*) ()> (&goo));

告诉编译器我真正想要使用哪个指针。

为我编写这个static_cast会使代码变得更加丑陋,所以我编写了一个包装函数,用于使用模板将函数指针转换为适当的函数:

template <typename R, typename... Args>
using Funptr_t = R (*) (Args...);

template <typename R, typename... Args>
Funptr_t<R, Args...> funptr (Funptr_t<R, Args...> ptr) {
    return static_cast<Funptr_t<R, Args...>> (ptr);
}

现在用法看起来好多了:

c (funptr<int, int> (&goo), 10);
c (funptr<void> (&goo));

我的问题是:你有更好的想法如何处理这种情况? 我很确定这在通用代码中经常发生。 所以,请给我一些建议。

理想的解决方案是如果我可以直接使用(X)和(Y),那么指向适当的重载的魔术技巧将使用A...并对调用者隐藏。

我的意思是,您始终可以明确指定模板参数:

c<int(int)>(&goo, 10);
c<void()>(&goo);

AFAIK在c无法做到这一点,因为F无法推导出(重载之间的歧义),并且为了使编译器推导出正确的类型,你需要在调用者方面改变一些东西。

如果C ++ 14可用,那么通用lambdas提供了“将重载集作为函数参数传递”的解决方案:

#define FWD(arg) static_cast<decltype(arg)&&>(arg)
auto goo_fn = [](auto&&... args) -> decltype(goo(FWD(args)...)) {
    return goo(FWD(args)...);
};

c(goo_fn, 10); // ok
c(goo_fn);     // ok

goo_fn是一个透明地(尽可能多)代表goo的重载集的lambda。 尾随的decltype是必要的,原因有两个:(1)确保返回类型是goo的重载是一个引用,以及(2)确保SFINAE友好性( decltype(auto)不会)。

暂无
暂无

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

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