Das Problem ist, dass der Compiler die Überladung nicht ausführen kann, da Ihre Funktionssignatur genau die gleiche wie die von Google ist. Sie könnten einen neuen Typ erstellen die Überlastung zB zu erzwingen:
#include <iostream>
// Google version
template <class T>
void print(const T& value, std::ostream& os) {
os << "Google print: " << value << std::endl;
}
// My wrapper type
template <class T>
struct PrintWrap {
const T& value_;
PrintWrap(const T& value): value_(value){}
};
template <class T>
PrintWrap<T> printWrap(const T& value) {
return PrintWrap<T>(value);
}
template <class T>
void print(const PrintWrap<T>& printWrap, std::ostream& os) {
os << "My special print: " << printWrap.value_ << std::endl;
}
int main() {
std::string value = "Hallo world";
print(printWrap(value), std::cout);
// your code goes here
return 0;
}
Im Falle Sie nicht die Kontrolle über den anrufenden Code, können Sie die notwendigen Funktionen in printWrap zB Bediener erforderlich Überlastung == unter Überlastung, wie dies die Bibliotheksfunktion (checkEqualTo) erfordert:
#include <iostream>
// Google version
template <class T>
void print(const T& value, std::ostream& os) {
os << "Google print: " << value << std::endl;
}
// My wrapper type
// :NOTE Overload what is required by Google, in this
// case lets assume operator== as example
template <class T>
struct PrintWrap {
const T& value_;
PrintWrap(const T& value): value_(value){}
friend bool operator==(const PrintWrap& lhs, const PrintWrap& rhs) {
return lhs.value_ == rhs.value_;
}
};
template <class T>
PrintWrap<T> printWrap(const T& value) {
return PrintWrap<T>(value);
}
template <class T>
void print(const PrintWrap<T>& printWrap, std::ostream& os) {
os << "My special print: " << printWrap.value_ << std::endl;
}
template <class T>
bool checkEqualTo(const T& lhs, const T& rhs) {
if (lhs == rhs) return true;
print(lhs, std::cout);
print(rhs, std::cout);
return false;
}
// Google code...
#define CHECK_EQUAL(x,y) checkEqualTo(x,y)
int main() {
std::string value = "Hallo world";
CHECK_EQUAL(printWrap(value), printWrap(value));
return 0;
}
EDIT
Sie auch einen Blick auf diese guide haben kann, die Dokumentation Gtest der ist con cerning print customization, bei der PrintTo im selben Namespace wie der fragliche Typ definiert wird, um ADL (Argument Dependent Lookup) zu verwenden.
Im Folgenden ein Beispiel für die Verwendung ADL für diesen Zweck ist, das, was sie für die Erweiterung ins Auge gefasst als Mechanismus ist, wäre es naht:
#include <iostream>
#include <cassert>
// Google version template <class T>
void print(const T& value, std::ostream& os) {
os << "Google print: " << value << std::endl;
}
namespace custom {
template <class T>
struct Printable : T
{
template <class...Args>
Printable(Args&&... args)
: T(std::forward<Args>(args)...)
{ }
};
template <class T>
void print(const Printable<T>& value, std::ostream& os) {
os << "My special print: " << value << std::endl;
}
} //custom
int main() {
custom::Printable<std::string> x = "my string";
custom::Printable<std::string> y = "my other string";
assert(! (x == y));
//found by ADL
print(x, std::cout);
return 0;
}
Hier oben, die Funktionsdeklaration im gleichen Namensraum wie das Argument Lookup-Vorrang, und daher existiert die Mehrdeutigkeit nicht. Sie müssen keine Druckversion verwenden (es gibt möglicherweise eine bessere vollständige Implementierung). Sie könnten je nach Bedarf einen Druck pro Typ haben.
Beachten Sie, dass der obige Code mein Beispiel ist. Gtest erfordert die Überlastung zu sein:
void PrintTo(const Bar& bar, ::std::ostream* os)...
Darüber hinaus erhalten Sie nur Operator < < für Ihre Art überlasten könnten, wie in ihrer Dokumentation erwähnt.
Beide Template-Funktionen haben die gleiche Signatur und das gleiche Template-Argument - daher kann der Compiler sie nicht unterscheiden. Was ist, wenn Sie Ihre Funktion wie folgt deklarieren: 'template void PrintTo (const C & val, :: std :: ostream * os) {...}'? –
vahancho
Ich glaube nicht, dass die Änderung des Argumentnamens irgendetwas verändern würde!Die Compiler-Fehlerausgabe sieht ebenfalls gleich aus. –
'void PrintTo (const QAVariant & value, :: std :: ostream * os);' Kann einige der Typen, nach denen Sie suchen, durch implizite Konvertierung erfassen, andernfalls müssen Sie wahrscheinlich eine separate Funktion für jeden Typ schreiben. –