Compiling the following code: #include <iostream> #include <sstream> #include <tuple> #include <type_traits>
namespace NS { struct Point { int x; int y; }; template <typename StreamType> inline StreamType& operator<<(StreamType& stream, const Point& obj) { return stream << std::make_tuple( obj.x, obj.y); } struct Serialize { template <typename ...T> struct for_each { for_each(const std::tuple<T...>& t) : t_(t) { } const std::tuple<T...>& t_; template <std::size_t pos = 0, typename StreamType> StreamType& operator()(StreamType& stream, typename std::enable_if<(pos >= sizeof...(T))>::type* = nullptr) { return stream; } template <std::size_t pos = 0, typename StreamType> StreamType& operator()(StreamType& stream, typename std::enable_if <(pos < sizeof...(T))>::type* = nullptr) { if (pos) { stream << stream.sep_; } stream << std::get<pos>(t_); return this->operator()<pos + 1>(stream); } }; template <typename ...T> Serialize(const std::tuple<T...>& t) : sep_(","), quoted_(true) { (*this) << t; } template <typename T> Serialize(const T& obj, bool autoProviders = true) : sep_(autoProviders ? "_" : ", "), quoted_(false) { NS::operator<<(*this, obj); } std::string str() const { return stream_.str(); } template <typename ...T> Serialize& operator<<(const std::tuple<T...>& t) { for_each<T...> functor(t); return functor(*this); } template <typename T> Serialize& operator<<(const T& t) { stream_ << t; return (*this); } Serialize& operator<<(const std::string& s) { if (!quoted_) { stream_ << s; } else { stream_ << '\'' << s << '\''; } return (*this); } std::ostringstream stream_; const char* sep_; bool quoted_; }; template <typename ...T> inline std::ostream& operator<<(std::ostream& stream, const std::tuple<T...>& t) { return stream << Serialize(t).str(); } } int main() { std::ostringstream os; NS::Point p = {1, 2}; os << p; return 0; } produces the error: clang++ --std=c++11 test_operator_adl.cpp test_operator_adl.cpp:17:17: error: call to function 'operator<<' that is neither visible in the template definition nor found by argument-dependent lookup return stream << std::make_tuple( ^ test_operator_adl.cpp:92:5: note: in instantiation of function template specialization 'NS::operator<<<std::basic_ostringstream<char> >' requested here os << p; ^ test_operator_adl.cpp:82:23: note: 'operator<<' should be declared prior to the call site inline std::ostream& operator<<(std::ostream& stream, const std:... ^ 1 error generated. I would have thought that since all the necessary definitions have been seen before the spot where the templates are instantiated and operator<< is used that we have satisfied the requirement that "operator<< should be declared prior to the call site". Is this a bug or I just don't understand things correctly? -- Jens Jorgensen jorgen...@lowtechsolutions.net This e-mail and its attachments are intended only for the individual or entity to whom it is addressed and may contain information that is confidential, privileged, inside information, or subject to other restrictions on use or disclosure. Any unauthorized use, dissemination or copying of this transmission or the information in it is prohibited and may be unlawful. If you have received this transmission in error, please notify the sender immediately by return e-mail, and permanently delete or destroy this e-mail, any attachments, and all copies (digital or paper). Unless expressly stated in this e-mail, nothing in this message should be construed as a digital or electronic signature. For additional important disclaimers and disclosures regarding KCG’s products and services, please click on the following link: http://www.kcg.com/legal/global-disclosures _______________________________________________ cfe-users mailing list cfe-users@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-users