i tried to find a way to disambiguate this code (at compile time) (since two days :-) -> get_value is ambugiuous.
#include <iostream>
template <typename T>
struct type2type {};
template<class T, int val>
struct BASE
{
static constexpr int get_value ( type2type< T > )
{
return val;
}
};
class X {};
class Y {};
struct A :
public BASE< X, 1 >,
public BASE< Y, 0 >
{};
int main ( int argc, char **argv )
{
A a {};
std::cout << a.get_value ( type2type< X >{} ) << std::endl;
}
This is a working runtime solution.
#include <iostream>
template <typename T>
struct type2type {};
template<class T>
struct VIRTUAL
{
int get_value () const
{
return get_value_from_BASE ( type2type< T > {} );
}
private:
virtual int get_value_from_BASE ( type2type< T > ) const = 0;
};
template<class T, int val>
class BASE :
public VIRTUAL< T >
{
virtual int get_value_from_BASE ( type2type< T > ) const override
{
return val;
}
};
class X {};
class Y {};
struct A :
public BASE< X, 1 >,
public BASE< Y, 0 >
{};
int main ( int argc, char **argv )
{
A a {};
std::cout << a.::VIRTUAL< X >::get_value () << std::endl;
}
Is there a solution?
Note: a possible way that i found is over std::is_base_of<>, but this is very limited ( template instantiation depth )
This is an ambiguous name lookup, which in the case of multiple inheritance hides the names in the look-up. It doesn't even get to checking which overload to use.
You can fix this by adding the following to struct A
's definition:
using BASE<X,1>::get_value;
using BASE<Y,0>::get_value;
These two statements add the name get_value
from both base classes to A, and thus the compiler can then move on with its dreary life and check them as overloads.