일부 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, Clang 및 ICC에서 예상대로 컴파일되고 작동하지만 GCC (trunk)로 컴파일 할 때 operator<<
line에 대한 모호한 오류가 발생합니다 os << elem << " "
. 그리고이 오류조차도 플래그 -std=c++17
또는로 컴파일 할 때만 나타납니다 -std=c++2a
.
이 오류에 대한 합리적인 것 같다 std::string
컴파일러는 기존의 함수 템플릿을 감지하기 때문에, 그 세계에 대한 operator<<
출력 스트림과를 받아 그 basic_string<CharT, Traits, Allocator>
으로, Allocator
형의 존재가 기본값 std::allocator
.
내 질문은 왜 적어도 3 개의 컴파일러가 컴파일하고 다른 3 개의 컴파일러와 함께 작동합니까? Clang은 적어도 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