I have a function in my code which only accepts a class member method as a template parameter. I need to call this method using a class method which is inherited from a parent class. Here is an example code of my problem:
template <class C>
class Test {
public:
template<typename R, R( C::* TMethod )()> // only a member function should be accepted here
void test() {}
};
class A {
public:
int a() { return 0; } // dummy method for inheritance
};
class B : public A {
public:
using A::a; // A::a should be declared in the B class declaration region
// int a() { return A::a(); } // if this lines is activated compliation works
};
int main() {
auto t = Test<B>();
t.test<int, &B::a>();
}
With the MSVC 2019 compiler the code compiles without problems. However the gcc produces following error:
<source>: In function 'int main()':
<source>:23:23: error: no matching function for call to 'Test<B>::test<int, &A::a>()'
23 | t.test<int, &B::a>();
| ~~~~~~~~~~~~~~~~~~^~
<source>:5:10: note: candidate: 'template<class R, R (B::* TMethod)()> void Test<C>::test() [with R (C::* TMethod)() = R; C = B]'
5 | void test() {}
| ^~~~
<source>:5:10: note: template argument deduction/substitution failed:
<source>:23:17: error: could not convert template argument '&A::a' from 'int (A::*)()' to 'int (B::*)()'
23 | t.test<int, &B::a>();
|
As far as I understand the gcc is still handling the type of B::a as A::a. On the cpp reference its saying that using
Introduces a name that is defined elsewhere into the declarative region where this using-declaration appears.
So in my opinion the using should transfer the A::a method to the declerativ region of B and therefor it should be handled as B::a. Am I wrong or is there a bug in GCC?
Here is the example on Compiler Explorer: https://godbolt.org/z/TTrd189sW
Error (active) E0304 no function template instance "Test<C>::test [with C=B]" matches argument list
. – GambettaB
, but the function does not become a member ofB
. Its type remains the same, since it refers to a member ofA
. – Finnellusing A::a;
does not mean "makeA::a
a member ofB
as well", it means "useB::a
as a synonym forA::a
". – Finnell