ฉันสร้างเทมเพลตฟังก์ชันสำหรับการพิมพ์คอนเทนเนอร์ stl บางส่วน
#include <iostream>
#include <vector>
#include <string>
template <template <typename, typename> class C, typename T, typename A>
std::ostream& operator<<(std::ostream& os, const C<T, A>& container)
{
for (auto& elem : container)
{
os << elem << " ";
}
return os;
}
int main()
{
std::vector<std::string> v { "One", "Two", "Three" };
std::cout << v << std::endl;
return 0;
}
คอมไพล์นี้และผลงานตามที่คาดไว้ MSVC, เสียงดังกราวและ ICC แต่เมื่อรวบรวมกับ GCC (ลำต้น) จะให้ ambigous ข้อผิดพลาดสำหรับบรรทัดoperator<<
os << elem << " "
และแม้กระทั่งข้อผิดพลาดนี้จะปรากฏเฉพาะเมื่อรวบรวมกับธงหรือ-std=c++17
-std=c++2a
ข้อผิดพลาดที่ดูเหมือนว่าเหมาะสมสำหรับstd::string
เนื่องจากคอมไพเลอร์ตรวจพบฟังก์ชั่นที่มีอยู่ที่แม่แบบสำหรับทั่วโลกoperator<<
ที่รับกระแส output และbasic_string<CharT, Traits, Allocator>
มีประเภทเป็นค่าเริ่มต้นให้Allocator
std::allocator
คำถามของฉันจะเป็นสาเหตุที่รวบรวมและทำงานร่วมกับ 3 คอมไพเลอร์อื่น ๆ จากความเข้าใจของฉันอย่างน้อยก็ใช้การใช้ไลบรารี่มาตรฐานเดียวกันบน linux เป็น gcc ดังนั้นจึงมีเทมเพลตฟังก์ชันเดียวกันสำหรับ operator<<
ข้อผิดพลาดที่รายงานคือ
error: ambiguous overload for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and 'const std::__cxx11::basic_string<char>')
และผู้สมัครทั้งสอง
note: candidate: 'std::ostream& operator<<(std::ostream&, const C<T, A>&) [with C = std::__cxx11::basic_string; T = char; A = std::char_traits<char>; std::ostream = std::basic_ostream<char>]'
note: candidate: 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&, const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]'
อาร์กิวเมนต์คอมไพเลอร์สำหรับ GCC, Clang และ ICC
-std=c++2a -O3 -Wall -Wextra -Wpedantic -Werror
สำหรับ MSVC
/std:c++latest /O2 /W3
ลิงค์ godbolt ที่บังคับ: https://godbolt.org/z/R_aSKR