मैंने कुछ स्टाल कंटेनरों की छपाई के लिए एक फंक्शन टेम्प्लेट बनाया
#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 (ट्रंक) के साथ संकलित करता है, तो यह operator<<
लाइन के लिए एक अस्पष्ट त्रुटि देता है os << elem << " "
। और यहां तक कि यह त्रुटि केवल ध्वज के साथ संकलन करते समय प्रकट होती है -std=c++17
या -std=c++2a
।
त्रुटि उचित प्रतीत होती है std::string
, क्योंकि, कंपाइलर एक मौजूदा फ़ंक्शन टेम्प्लेट का पता लगाता है जो वैश्विक के लिए operator<<
एक आउटपुट स्ट्रीम और ए को स्वीकार करता है basic_string<CharT, Traits, Allocator>
, जिस Allocator
प्रकार को डिफ़ॉल्ट किया जा रहा है std::allocator
।
मेरा प्रश्न यह होगा कि यह अन्य 3 संकलकों के साथ क्यों संकलित और काम करता है, मेरी समझ से, क्लैंग कम से कम, एक ही मानक पुस्तकालय कार्यान्वयन को 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>]'
जीसीसी, क्लैंग और आईसीसी के लिए संकलक तर्क
-std=c++2a -O3 -Wall -Wextra -Wpedantic -Werror
MSVC के लिए एक
/std:c++latest /O2 /W3
अनिवार्य Godbolt लिंक: https://godbolt.org/z/R_aSKR