1

I have C<T> that manage a specific primitive type, T.
I want to group all functions of C<int> and C<float> into Utility for my ease of usage.

template<typename T> class B{};
template<typename T> class C{
    public: static void foo(B<T> bt){} 
    /** complex implemention in .cpp (I use explicit instantiation) */
    /** a lot of functions!!!!!, each one with a lot of parameters */
};
class Utility: public C<int>,public C<float>{};
int main(){
    B<int> bInt;
    Utility::foo(bInt); //I don't want to change this line
}

Coliru MCVE
I expect Utility::foo(bInt) to have same meaning as C<int>::foo(bInt), but I got this error :-

main.cpp: In function 'int main()':
main.cpp:9:14: error: reference to 'foo' is ambiguous
    9 |     Utility::foo(bInt); //I don't want to change this line
      |              ^~~
main.cpp:3:25: note: candidates are: 'static void C<T>::foo(B<T>) [with T = float]'
    3 |     public: static void foo(B<T> bt){}
      |                         ^~~
main.cpp:3:25: note:                 'static void C<T>::foo(B<T>) [with T = int]'
 

I don't want to change how foo is called.
I like the way it is, except that it doesn't compile.
It looks like compiler fail to deduce and call a correct T-function. How to fix the compile error?

Note that I have many functions inside C.
cigien's solution works well, except that it can be tedious for my case.

Similar question : Ambiguous multiple inheritance of template classes (very tedious for my case)

cppBeginner
  • 1,114
  • 9
  • 27

1 Answers1

2

You can bring in the specific versions of foo that you need into C, like this:

class Utility : public C<int>, public C<float>
{
  public:
    using C<int>::foo;
    using C<float>::foo;
};

Now template argument deduction can deduce the right foo to call.

Here's a demo.

cigien
  • 57,834
  • 11
  • 73
  • 112