Poniższy kod może rozwiązać ten problem niejednoznaczności:
#include <iostream>
#include <string>
// Helper class providing a function call
template <typename T>
class PrintHelper
{
protected:
void print_impl(const T& t) { std::cout << t << std::endl; }
};
// Provides a print method for each type listed
template <typename... Ts>
class Printer : public PrintHelper<Ts>...
{
public:
template <typename U>
void print(const U& u) {
PrintHelper<U>::print_impl(u);
};
};
int main()
{
Printer<int, std::string> p;
p.print(std::string("Hello World")); // Ambiguous Call
}
co nie jest bardzo dobre, bo od wymóg, że typ U (wydedukowany podczas rozmowy) jest dokładnie jednym z nich e typy na liście typów variadic. Być może uda ci się trochę poprawić sytuację, aby rozwiązać ten problem. Przy odrobinie szablonowej magii i Sfinae, prawdopodobnie możesz rozwiązać ten problem dość łatwo (ale na pewno nie jest tak schludny i czysty).
Problem niejednoznaczności nie jest związany z wykorzystaniem szablonów lub szablonów variadic, oczywiście jest to prosta aplikacja do reguł wyszukiwania członków (sekcja 10.2/2 normy), tj. Często nazywana "zasady ukrywania członków". Jeśli wziąć tę prostszą wersję non-szablon, otrzymasz ten sam problem dwuznaczności, ale z bardzo prostego rozwiązania IT:
struct IntPrinter {
void print(const int& i) { std::cout << i << std::endl; };
};
struct StringPrinter {
void print(const std::string& s) { std::cout << s << std::endl; };
};
struct IntStringPrinter : IntPrinter, StringPrinter {
using IntPrinter::print; // These using-statements will solve the problem
using StringPrinter::print; // by importing all 'print' functions to the same
// overload resolution level.
};
Więc problem tutaj jest naprawdę, że dwuznaczność powstaje przed kompilator nawet prób aby zastosować normalne reguły dotyczące przeciążania, ponieważ najpierw próbuje ustalić, która gałąź dziedziczenia ma zostać znaleziona, aby znaleźć funkcję (funkcje) członka, a następnie rozwiąże przeciążenie tylko na jednym poziomie dziedziczenia. Problemem podczas korzystania z szablonów variadic jest to, że nie istnieje żaden sposób rozpakowania zestawu instrukcji "using" w celu zaimportowania wszystkich funkcji drukowania do tego samego poziomu dziedziczenia. Jeśli ktokolwiek wie, jak rozpakować takie instrukcje użycia, jestem uszy. Być może będziesz musiał wrócić do rozwiązań sprzed-variadic-template (jak szablon ogólny z 10 argumentami i specjalizować się we wszystkich dziesięciu wersjach).
sam problem z gcc 4.7.2 (w [liveworkspace] (http://liveworkspace.org/code/1a4YN8$0)). Dziękujemy za skopiowanie/wklejenie przykładu btw. –
klang 3.2 trunk 165721 mówi: 'error: member 'print' znaleziony w wielu klasach bazowych różnych typów' – user786653
Zobacz także [to pytanie] (http://stackoverflow.com/questions/5368862/why-do-multiple-inherited -funkcje-z takimi samymi nazwami, ale różne podpisy-nie). Jest to w istocie problem kombinacji reguł ukrywania i bardzo ograniczonych możliwości rozpakowywania argumentów szablonu variadic. –