overload-resolution

C++ templated function overloading rules

可紊 提交于 2019-12-01 04:40:21
问题 When overloading a templated function, how should the compiler chose which version of the function to call if it has the option to either: Call a templated version of the function (such as func<T>(foo) ). Call an overloaded version of the function which is not itself templated but where the type of the parameter being passed to the function inherits from the type specified in the overloaded function template. Consider the following C++ code: #include <stdio.h> struct Parent {}; struct Child :

member function hiding free function

大兔子大兔子 提交于 2019-12-01 03:16:52
void foo(int) { } class X { void foo() { } void bar() { foo(42); // error: no matching function for call to 'X::foo(int)' // note: candidate is: // note: void X::foo() // note: candidate expects 0 arguments, 1 provided } }; Why is C++ unable to call the free function (which is the only one with the correct signature)? The logical reason is Consistency . Suppose as per the suggestion, compiler resolves foo(42) to ::foo(int) . Now after sometime, if you change X::foo() to X::foo(int) then foo(42) will be resolved to X::foo(int) . Which is not consistent. That is the also the reason why derived

How does template argument deduction work when an overloaded function is involved as an argument?

ぃ、小莉子 提交于 2019-12-01 02:15:01
This is the more sophisticated question mentioned in How does overload resolution work when an argument is an overloaded function? Below code compiles without any problem : void foo() {} void foo(int) {} void foo(double) {} void foo(int, double) {} // Uncommenting below line break compilation //template<class T> void foo(T) {} template<class X, class Y> void bar(void (*f)(X, Y)) { f(X(), Y()); } int main() { bar(foo); } It doesn't appear a challenging task for template argument deduction - there is only one function foo() that accepts two arguments. However, uncommenting the template overload

How does overload resolution work when an argument is an overloaded function?

寵の児 提交于 2019-12-01 02:04:53
问题 Preamble Overload resolution in C++ can be an overly complex process. It takes quite a lot of mental effort to understand all of the C++ rules that govern overload resolution. Recently it occurred to me that the presence of the name of an overloaded function in the argument list can add to the complexity of overload resolution. Since it happened to be a widely used case, I posted a question and received an answer that allowed me to better understand the mechanics of that process. However, the

member function hiding free function

旧巷老猫 提交于 2019-11-30 23:47:46
问题 void foo(int) { } class X { void foo() { } void bar() { foo(42); // error: no matching function for call to 'X::foo(int)' // note: candidate is: // note: void X::foo() // note: candidate expects 0 arguments, 1 provided } }; Why is C++ unable to call the free function (which is the only one with the correct signature)? 回答1: The logical reason is Consistency . Suppose as per the suggestion, compiler resolves foo(42) to ::foo(int) . Now after sometime, if you change X::foo() to X::foo(int) then

Why variadic template constructor matches better than copy constructor?

别等时光非礼了梦想. 提交于 2019-11-30 23:40:35
问题 The following code does not compile: #include <iostream> #include <utility> struct Foo { Foo() { std::cout << "Foo()" << std::endl; } Foo(int) { std::cout << "Foo(int)" << std::endl; } }; template <typename T> struct Bar { Foo foo; Bar(const Bar&) { std::cout << "Bar(const Bar&)" << std::endl; } template <typename... Args> Bar(Args&&... args) : foo(std::forward<Args>(args)...) { std::cout << "Bar(Args&&... args)" << std::endl; } }; int main() { Bar<Foo> bar1{}; Bar<Foo> bar2{bar1}; } Compiler

Make foo(derived_object) call foo(Base const&) instead of template function?

ぐ巨炮叔叔 提交于 2019-11-30 18:13:14
问题 Given this code: template< class C > void foo( C const& o ) { o.nosuch(); } struct Base {}; void foo( Base const& ) {} struct Derived: Base {}; auto main() -> int { Derived d; foo( d ); // !Invokes template. } … I want the call to invoke the overload defined for Base , without having to define an overload or template specialization for Derived . The goal is to be able to apply foo to all kinds of objects, not just Base (and Derived ) objects, with a generic implementation for most kinds of

Why doesn't narrowing affect overload resolution?

半城伤御伤魂 提交于 2019-11-30 16:26:31
问题 Consider the following: struct A { A(float ) { } A(int ) { } }; int main() { A{1.1}; // error: ambiguous } This fails to compile with an error about an ambiguous overload of A::A . Both candidates are considered viable, because the requirement is simply: Second, for F to be a viable function, there shall exist for each argument an implicit conversion sequence (13.3.3.1) that converts that argument to the corresponding parameter of F . While there is an implicit conversion sequence from double

Deducing template arguments during partial ordering when parameters are function parameter pack

非 Y 不嫁゛ 提交于 2019-11-30 15:20:27
N4527 14.8.2.4 [temp.deduct.partial] 3 The types used to determine the ordering depend on the context in which the partial ordering is done: (3.1) — In the context of a function call, the types used are those function parameter types for which the function call has arguments. (3.2) — In the context of a call to a conversion function, the return types of the conversion function templates are used. (3.3) — In other contexts (14.5.6.2) the function template’s function type is used. 4 Each type nominated above from the parameter template and the corresponding type from the argument template are

Overload resolution between template members in base and derived classes

不想你离开。 提交于 2019-11-30 15:00:23
Microsoft compiler (Visual Studio 2017 15.2) rejects the following code: #include <type_traits> struct B { template<int n, std::enable_if_t<n == 0, int> = 0> void f() { } }; struct D : B { using B::f; template<int n, std::enable_if_t<n == 1, int> = 0> void f() { } }; int main() { D d; d.f<0>(); d.f<1>(); } The error is: error C2672: 'D::f': no matching overloaded function found error C2783: 'void D::f(void)': could not deduce template argument for '__formal' note: see declaration of 'D::f' Clang also rejects it: error: no matching member function for call to 'f' d.f<0>(); ~~^~~~ note: