这里有一篇文章询问我认为与我的目的等效的内容(函数的地址而不是类型(,但这个问题已经有5年了;唯一的答案是可能没有适当的解决方案 - 没有提出特定原因 - 并提供部分解决方案,要求一个新函数显式调用每个有问题的ADL函数只是为了利用lambda语义。
template <typename T>
void (*get_swap())(T&, T&) {
return [](T& x, T& y) { return swap(x, y); };
}
我可以让它更通用一些:
template<typename... T>
void (*get_func())(T &&... t) {
return [](T &&... u) { return func(std::forward<T>(u)...); };
}
显然func
也应该是一个参数 - 可能是一个模板参数 - 但这开始崩溃。
template<typename S, typename... T>
void (*get_func())(S (*func)(T &&...), T &&... t) {
return [](T &&... u) { return func(std::forward<T>(u)...); };
}
答案继续使用如下get_swap
:
auto f1 = get_swap<a::b>();
这似乎是道路的尽头:f1
是通过函数的显式实例化键入的;ADL 在窗外。
考虑std::make_tuple
:您已经知道std::make_tuple<T...>
在T &&... t
上是可调用的,并且调用std::make_tuple(std::forward<T>(t)...)
等效于在T...
上显式实例化它。如果你不知道呢?也许某些模板参数是值,或者参数以某种方式打包,或者最佳候选者恰好包含一些具有默认值的额外参数。你可能会为 RTFM 提出论据,或者等待某种反射概念出现,但我认为这是一个有效的问题;显然,编译器知道它通过 ADL 解析的函数的地址和类型。如果我将其添加为一个功能,我不知道从语法开始(尽管我希望它遵循declval
和decltype
,也许是declfunc
,返回最外层调用的类型。
简而言之,我正在寻找一种问"如果我提供这些论点,你会怎么称呼?"和/或"你会称之为(...("的方法。
Meta:我故意省略了特定于版本的标签,以防解决方案可能存在于较新版本(或提案等(中。对于它的价值,我使用的是主要来自 C++11 背景的 C++14。这是一种学术兴趣,至少目前是这样。另外,我的目标是中性语气,但如果听起来不是这样,我无意轻视我引用的答案的作者。
不,C++ 不会暴露这一点。
如果你有一个实际的用例,人们可以提供解决方法或解决方案来解决底层问题。 但是当你在抽象中要求一个非常具体的功能时,答案是C++没有提供该特定功能。
您可能会重写编译器来执行此操作,但这将不再C++。