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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With