模棱两可:优先考虑重载 f(A&) 而不是 f(A)
Ambiguous : Prioritize overloading of f(A&) over f(A)
如何优先级(告诉编译器)在"函数接收值"(#A)上使用"函数接收参考"(#B)?
#include <iostream>
using namespace std;
class Heavy{/* ...... */}; //a complex class
Heavy generateHeavy(){
return Heavy();
}
void f(Heavy x){ //#A I want LOW priority.
std::cout<<"case 1: pass by value"<<std::endl;
}
void f(Heavy& x){ //#B I want HIGH priority. (save CPU for big object)
std::cout<<"case 2: pass by reference"<<std::endl;
}
int main() {
//vvvv Here is existing code base that I don't want to touch.
f(generateHeavy()); //compiler call case 1 -> ok (I prefer reference, though)
Heavy heavy;
f(heavy); //should call case 2, but compiler fail (ambiguous) <= question
return 0;
}
这个问题是我第一次尝试将Sfinae扩展到现实情况,如果可能的话,该案例更喜欢通过参考。
按照您问的字面上的方式是
template <typename T = void>
std::enable_if_t<std::is_same<T, void>::value> f(Heavy x) { ... }
void f(Heavy& x) { ... }
第一个是函数模板,但仅允许T = void
。第二个不是。所有其他是相等的,非模板优先于模板。
现在,在实际代码中,您可能不会这样做。您会查看您希望支持哪些呼叫,并找到适合这些电话的更合适的方法。@StoryTeller建议&&
:
void f(Heavy &&) { ... }
void f(Heavy &) { ... }
这意味着当您拥有rvalue(例如功能结果)时,Heavy &&
过载将被调用。这通常很好,但请注意,它与您要求的不完全相同:
const Heavy c;
f(c);
您要要求的会呼叫f(Heavy)
。相反,使用Heavy &&
过载,没有任何过载可以接受此。
额外的过载void f(const Heavy &)
可以涵盖这一点。问题中没有足够的信息来判断这是否是适合您用例的方法,但是您应该能够弄清楚自己。
相关文章:
- 模棱两可的重载模板
- 调用重载的"<大括号括起来的初始值设定项列表>"对于对来说就足够了是模棱两可的
- VSCode 说 std::chrono 是模棱两可的,如果运算符<<重载
- 修复重载运算符的使用'+'模棱两可?
- 涉及自定义类的奇怪的模棱两可的重载
- 给定一个已经定义的模板函数,是否可以用另一个模板函数重载它而不会模棱两可
- 模棱两可:优先考虑重载 f(A&) 而不是 f(A)
- 看似模棱两可的模板函数重载
- 重载函数的调用 - 以继承的类作为参数 - 是模棱两可的
- C++ libconfig 模棱两可的重载
- ISO C++ 表示这些是模棱两可的运算符重载
- 为什么下面的运算符重载是模棱两可的
- 模棱两可的重载函数 - 如何以及为什么
- C++模板,模棱两可的重载
- 为什么这些重载不模棱两可?
- c++中模棱两可的函数重载
- 对重载函数的模棱两可的调用,即使一个更专业
- 重载函数会产生模棱两可的错误
- Gtkmm,重载的'Scale()'的调用是模棱两可的
- 调用重载<大括号括起来的初始值设定项列表>是模棱两可的,如何处理?