Tôi đang cố gắng ra các mã được trình bày bởi Sean Chánh tại buổi nói chuyện tại GoingNative 2.013-"Inheritance is the base class of evil". (mã từ slide cuối cùng có sẵn tại https://gist.github.com/berkus/7041546Tại sao trình biên dịch chọn quá tải hàm không chính xác trong trường hợp này?
tôi đã cố gắng để đạt được cùng một mục tiêu riêng của tôi, nhưng tôi có thể' t hiểu tại sao đoạn code dưới đây sẽ không hành động như tôi mong đợi nó.
#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;
}
phiên bản này xử lý in int
tốt, nhưng thất bại trong việc biên dịch trong trường hợp thứ hai là trình biên dịch không biết làm thế nào để sử dụng MyClass
với operator<<
.Tôi không thể hiểu tại sao trình biên dịch sẽ không chọn quá tải thứ hai được cung cấp riêng cho th e MyClass
. Mã biên dịch và hoạt động tốt nếu tôi thay đổi tên của phương thức :: draw() và xóa số tham chiếu không gian tên toàn cầu ::
khỏi cơ thể của nó hoặc nếu tôi thay đổi chức năng vẽ toàn cầu của MyClass thành một chuyên môn mẫu hoàn chỉnh.
Thông báo lỗi tôi nhận được là như dưới đây, sau đó là một loạt các candidate function not viable...
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()));
^
Tại sao phiên bản mẫu của toàn cầu bốc mẫu chức năng choosen trong tình trạng quá tải chức năng MyClass? Có phải vì tham chiếu mẫu là tham lam? Làm thế nào để giải quyết vấn đề này?
Tôi đã thử mã của bạn với MSVC13 và nó biên dịch tốt, sử dụng phiên bản int trong trường hợp đầu tiên và phiên bản MyClass với phiên bản thứ hai. Bạn nên thêm thông tin về trình biên dịch bạn đang sử dụng – Christophe
Tôi sử dụng tính năng chuyển đổi tiếng kêu phiên bản 3.5.0 (thẻ/RELEASE_350/final). –
[Câu hỏi khác có cùng nguyên tắc] (http://stackoverflow.com/questions/8501294/different-behavior-for-qualified-and-unqualified-name-lookup-for-template/8501421#8501421) –