Ich versuche, den Code von Sean Elternteil in seinem Vortrag auf GoingNative 2013 präsentiert out - "Inheritance is the base class of evil". (Code aus der letzten Folie erhältlich bei https://gist.github.com/berkus/7041546Warum wählt der Compiler in diesem Fall die falsche Funktionsüberladung?
ich das gleiche Ziel zu erreichen, habe versucht, auf meinem eigenen, aber ich kann‘ t verstehen, warum der folgende Code nicht handeln, wie ich es erwarten.
#include <boost/smart_ptr.hpp>
#include <iostream>
#include <ostream>
template <typename T>
void draw(const T& t, std::ostream& out)
{
std::cout << "Template version" << '\n';
out << t << '\n';
}
class object_t
{
public:
template <typename T>
explicit object_t (T rhs) : self(new model<T>(rhs)) {};
friend void draw(const object_t& obj, std::ostream& out)
{
obj.self->draw(out);
}
private:
struct concept_t
{
virtual ~concept_t() {};
virtual void draw(std::ostream&) const = 0;
};
template <typename T>
struct model : concept_t
{
model(T rhs) : data(rhs) {};
void draw(std::ostream& out) const
{
::draw(data, out);
}
T data;
};
boost::scoped_ptr<concept_t> self;
};
class MyClass {};
void draw(const MyClass&, std::ostream& out)
{
std::cout << "MyClass version" << '\n';
out << "MyClass" << '\n';
}
int main()
{
object_t first(1);
draw(first, std::cout);
const object_t second((MyClass()));
draw(second, std::cout);
return 0;
}
Diese Version Griffe Druck int
in Ordnung, aber nicht im zweiten Fall zu kompilieren, wie der Compiler nicht weiß, wie MyClass
zu verwenden, um mit operator<<
. Ich kann nicht verstehen, warum der Compiler nicht die zweite Überladung speziell für th auswählen wird e MyClass
. Der Code kompiliert und funktioniert gut, wenn ich den Namen der model :: draw() -Methode ändere und den globalen Namespace-Bezeichner ::
aus seinem Hauptteil lösche oder wenn ich die globale MyClass-Funktion zu einer vollständigen Template-Spezialisierung ändere.
Die Fehlermeldung I ist wie unten, danach ein paar candidate function not viable...
ist
t76_stack_friend_fcn_visibility.cpp:9:9: error: invalid operands to binary expression ('std::ostream' (aka 'basic_ostream<char>') and 'const MyClass')
out << t << '\n';
~~~^~
t76_stack_friend_fcn_visibility.cpp:36:15: note: in instantiation of function template specialization 'draw<MyClass>' requested here
::draw(data, out);
^
t76_stack_friend_fcn_visibility.cpp:33:9: note: in instantiation of member function 'object_t::model<MyClass>::draw' requested here
model(T rhs) : data(rhs) {};
^
t76_stack_friend_fcn_visibility.cpp:16:42: note: in instantiation of member function 'object_t::model<MyClass>::model' requested here
explicit object_t (T rhs) : self(new model<T>(rhs)) {};
^
t76_stack_friend_fcn_visibility.cpp:58:20: note: in instantiation of function template specialization 'object_t::object_t<MyClass>' requested here
const object_t second((MyClass()));
^
Warum ist die Template-Version der globalen draw Template-Funktion über die MyClass Funktion Überlastung gewählt? Liegt es daran, dass die Vorlagenreferenz gierig ist? Wie behebe ich dieses Problem?
Ich habe versucht, Ihren Code mit MSVC13 und es kompiliert gut, verwendet die int-Version im ersten Fall und die MyClass-Version mit dem zweiten. Sie sollten infor über Compiler Sie verwenden – Christophe
Ich benutze clang - Version Clang Version 3.5.0 (Tags/RELEASE_350/final). –
[Eine andere Frage mit dem gleichen Prinzip] (http://stackoverflow.com/questions/8501294/different-behavior-for-qualified-and-unqualified-name-lookup-for-template/8501421#8501421) –