Tôi đang cố gắng in đẹp một container STL. Những gì tôi đang cố gắng để in elemets của một container tách biệt với một dấu phân cách. Tuy nhiên tôi đã gặp một số vấn đề.Mẫu quá tải nhà điều hành ostream
1. g ++ vs VC++
ostream& operator<<(ostream& o, const vector<string>& v) {
copy(v.begin(), v.end(), std::ostream_iterator<string>(o,","));
}
int main()
{
vector<string> s_v;
s_v.push_back("one");
s_v.push_back("two");
cout << s_v;
}
g ++ (gcc phiên bản 4.4.0 trên mingw32) có thể biên dịch nó một hoạt động tốt. VC++ (Visual Studio 9) không thể biên dịch mã này.
error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'const std::string' (or there is no acceptable conversion)
1> c:\program files (x86)\microsoft visual studio 9.0\vc\include\ostream(653): could be 'std::basic_ostream<_Elem,_Traits> &std::operator <<<char,std::char_traits<char>>(std::basic_ostream<_Elem,_Traits> &,const char *)'
1> with
1> [
tại sao điều này? Mã này có phải là bất hợp pháp không? hoặc nó chỉ là VC++ beign VC++?
2. Biên dịch ngắt biến mẫu chưa sử dụng.
nếu bây giờ tôi thêm một mẫu để các ostream như thế này (nó không được sử dụng, chỉ cần ngồi đó)
template <typename T> // <----- Here
ostream& operator<<(ostream& o, const vector<string>& v) {
copy(v.begin(), v.end(), std::ostream_iterator<string>(o,","));
}
int main()
{
vector<string> s_v;
s_v.push_back("one");
s_v.push_back("two");
cout << s_v;
}
gcc không thể phù hợp với các nhà điều hành nữa.
error: no match for 'operator<<' in 'std::cout << s_v'
and a lot more candidates...
Tại sao? mẫu không được sử dụng. Nó có quan trọng không?
EDIT: Giải pháp này được giải quyết. Tôi phải trở về o;
3. qua sử dụng mẫu
template <typename T>
ostream& operator<<(ostream& o, const vector<T>& v) {
copy(v.begin(), v.end(), std::ostream_iterator<T>(o,","));
return o; // Edited
}
int main()
{
vector<string> s_v;
s_v.push_back("one");
s_v.push_back("two");
vector<int> i_v;
i_v.push_back(1);
i_v.push_back(2);
cout << s_v;
cout << i_v;
}
Nếu tôi biết sử dụng các kiểu mẫu. g + + có thể biên dịch nó nhưng sau đó chấm dứt với một ngoại lệ.
terminate called after throwing an instance of 'std::bad_cast'
what(): std::bad_cast
VC++ chỉ đang ngồi và xem gcc làm tất cả những việc này. Không biên dịch bất kỳ thứ gì trong số họ.
Ai đó có thể làm rõ điều này cho tôi không? Cảm ơn bạn.
Xác định toán tử của bạn trong không gian tên std. Bạn sẽ thấy sự khác biệt – PiotrNycz
Nếu trình biên dịch không thể suy ra loại đối số mẫu, bạn phải tự cung cấp nó. Vì vậy, nếu bạn có 'mẫu void Foo() {...}', bạn cần sử dụng 'Foo ()'. Rõ ràng, bạn không thể làm điều đó khi bạn quá tải một toán tử. Khi bạn _do_ sử dụng 'T', trình biên dịch có thể suy ra kiểu của nó, và đây là lý do tại sao nó hoạt động. –
zneak
Ngoài ra, ví dụ cuối cùng của bạn [chạy tốt] (http://ideone.com/mLJcTI) trên ideone. Bạn có thể muốn thêm 'return o;' vào toán tử '' của bạn. Điều này rất có thể sẽ làm hỏng chương trình của bạn nếu bạn đã làm 'cout << s_v << i_v'. – zneak