I want to support ostream for std::optional<T>
. My problem is std::optional<user defined type>
is captured by the new function that I have added, but std::optional<int>
is not captured.
Inside foo.h, I have the following code
template <typename T> std::ostream& operator<<(std::ostream& stream, const std::optional<T>& info) { if (info) { stream << *info; } else { stream << "None"; } return stream; }
Inside types.h:
struct MyType { ... ... }; inline std::ostream& operator<<(std::ostream& stream, const MyType& my_type) { ... return stream; }
Inside pqr.h
#include <"foo.h"> #include <"types.h"> struct ABC { std::optional<int> a; std::optional<MyType> b; } inline std::ostream& operator<<(std::ostream& stream, const ABC& abc) { stream << abc.a; //commenting this line solves the issue stream << abc.b; //Printing userdefined structure has no issues }
Commenting on the line
stream << abc.
solves the issue. It is so weird that my template code is not captured for std::optional<int>
, but captured for my user-defined type std::optional<MyType>
. The even weirder part is that both the lines are next to each other in the same file.
COMPILATION LOG:
error: invalid operands to binary expression ('basic_ostream<char, std::__1::char_traits<char> >' and 'const std::optional<int>') stream << abc.a; ~~~~^ ~~~~~~~ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:219:20: note: candidate function not viable: no known conversion from 'const std::optional<int>' to 'const void *' for 1st argument; take the address of the argument with & basic_ostream& operator<<(const void* __p); ^ /usr/lib/llvm-9/bin/../include/c++/v1/type_traits:4034:3: note: candidate function template not viable: no known conversion from 'basic_ostream<char, std::__1::char_traits<char> >' to 'std::byte' for 1st argument operator<< (byte __lhs, _Integer __shift) noexcept ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:195:20: note: candidate function not viable: no known conversion from 'const std::optional<int>' to 'std::__1::basic_ostream<char> &(*)(std::__1::basic_ostream<char> &)' for 1st argument basic_ostream& operator<<(basic_ostream& (*__pf)(basic_ostream&)) ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:199:20: note: candidate function not viable: no known conversion from 'const std::optional<int>' to 'basic_ios<std::__1::basic_ostream<char, std::__1::char_traits<char> >::char_type, std::__1::basic_ostream<char, std::__1::char_traits<char> >::traits_type> &(*)(basic_ios<std::__1::basic_ostream<char, std::__1::char_traits<char> >::char_type, std::__1::basic_ostream<char, std::__1::char_traits<char> >::traits_type> &)' (aka 'basic_ios<char, std::__1::char_traits<char> > &(*)(basic_ios<char, std::__1::char_traits<char> > &)') for 1st argument basic_ostream& operator<<(basic_ios<char_type, traits_type>& ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:204:20: note: candidate function not viable: no known conversion from 'const std::optional<int>' to 'std::__1::ios_base &(*)(std::__1::ios_base &)' for 1st argument basic_ostream& operator<<(ios_base& (*__pf)(ios_base&)) ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:207:20: note: candidate function not viable: no known conversion from 'const std::optional<int>' to 'bool' for 1st argument basic_ostream& operator<<(bool __n); ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:208:20: note: candidate function not viable: no known conversion from 'const std::optional<int>' to 'short' for 1st argument basic_ostream& operator<<(short __n); ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:209:20: note: candidate function not viable: no known conversion from 'const std::optional<int>' to 'unsigned short' for 1st argument basic_ostream& operator<<(unsigned short __n); ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:210:20: note: candidate function not viable: no known conversion from 'const std::optional<int>' to 'int' for 1st argument basic_ostream& operator<<(int __n); ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:211:20: note: candidate function not viable: no known conversion from 'const std::optional<int>' to 'unsigned int' for 1st argument basic_ostream& operator<<(unsigned int __n); ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:212:20: note: candidate function not viable: no known conversion from 'const std::optional<int>' to 'long' for 1st argument basic_ostream& operator<<(long __n); ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:213:20: note: candidate function not viable: no known conversion from 'const std::optional<int>' to 'unsigned long' for 1st argument basic_ostream& operator<<(unsigned long __n); ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:214:20: note: candidate function not viable: no known conversion from 'const std::optional<int>' to 'long long' for 1st argument basic_ostream& operator<<(long long __n); ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:215:20: note: candidate function not viable: no known conversion from 'const std::optional<int>' to 'unsigned long long' for 1st argument basic_ostream& operator<<(unsigned long long __n); ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:216:20: note: candidate function not viable: no known conversion from 'const std::optional<int>' to 'float' for 1st argument basic_ostream& operator<<(float __f); ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:217:20: note: candidate function not viable: no known conversion from 'const std::optional<int>' to 'double' for 1st argument basic_ostream& operator<<(double __f); ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:218:20: note: candidate function not viable: no known conversion from 'const std::optional<int>' to 'long double' for 1st argument basic_ostream& operator<<(long double __f); ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:220:20: note: candidate function not viable: no known conversion from 'const std::optional<int>' to 'basic_streambuf<std::__1::basic_ostream<char, std::__1::char_traits<char> >::char_type, std::__1::basic_ostream<char, std::__1::char_traits<char> >::traits_type> *' (aka 'basic_streambuf<char, std::__1::char_traits<char> > *') for 1st argument basic_ostream& operator<<(basic_streambuf<char_type, traits_type>* __sb); ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:223:20: note: candidate function not viable: no known conversion from 'const std::optional<int>' to 'std::nullptr_t' (aka 'nullptr_t') for 1st argument basic_ostream& operator<<(nullptr_t) ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:760:1: note: candidate function template not viable: no known conversion from 'const std::optional<int>' to 'char' for 2nd argument operator<<(basic_ostream<_CharT, _Traits>& __os, char __cn) ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:793:1: note: candidate function template not viable: no known conversion from 'const std::optional<int>' to 'char' for 2nd argument operator<<(basic_ostream<char, _Traits>& __os, char __c) ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:800:1: note: candidate function template not viable: no known conversion from 'const std::optional<int>' to 'signed char' for 2nd argument operator<<(basic_ostream<char, _Traits>& __os, signed char __c) ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:807:1: note: candidate function template not viable: no known conversion from 'const std::optional<int>' to 'unsigned char' for 2nd argument operator<<(basic_ostream<char, _Traits>& __os, unsigned char __c) ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:821:1: note: candidate function template not viable: no known conversion from 'const std::optional<int>' to 'const char *' for 2nd argument operator<<(basic_ostream<_CharT, _Traits>& __os, const char* __strn) ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:867:1: note: candidate function template not viable: no known conversion from 'const std::optional<int>' to 'const char *' for 2nd argument operator<<(basic_ostream<char, _Traits>& __os, const char* __str) ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:874:1: note: candidate function template not viable: no known conversion from 'const std::optional<int>' to 'const signed char *' for 2nd argument operator<<(basic_ostream<char, _Traits>& __os, const signed char* __str) ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:882:1: note: candidate function template not viable: no known conversion from 'const std::optional<int>' to 'const unsigned char *' for 2nd argument operator<<(basic_ostream<char, _Traits>& __os, const unsigned char* __str) ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:1066:1: note: candidate function template not viable: no known conversion from 'const std::optional<int>' to 'const std::__1::error_code' for 2nd argument operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __ec) ^ /usr/lib/llvm-9/bin/../include/c++/v1/random:3895:1: note: candidate function template not viable: no known conversion from 'const std::optional<int>' to 'const std::__1::bernoulli_distribution' for 2nd argument operator<<(basic_ostream<_CharT, _Traits>& __os, const bernoulli_distribution& __x) ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:753:1: note: candidate template ignored: deduced conflicting types for parameter '_CharT' ('char' vs. 'std::__1::optional<int>') operator<<(basic_ostream<_CharT, _Traits>& __os, _CharT __c) ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:814:1: note: candidate template ignored: could not match 'const _CharT *' against 'std::optional<int>' operator<<(basic_ostream<_CharT, _Traits>& __os, const _CharT* __str) ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:1049:1: note: candidate template ignored: could not match 'basic_string' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:1039:1: note: candidate template ignored: requirement '!is_lvalue_reference<std::__1::basic_ostream<char> &>::value' was not satisfied [with _Stream = std::__1::basic_ostream<char> &, _Tp = std::__1::optional<int>] operator<<(_Stream&& __os, const _Tp& __x) ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:1057:1: note: candidate template ignored: could not match 'basic_string_view' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:1074:1: note: candidate template ignored: could not match 'shared_ptr' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p) ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:1086:1: note: candidate template ignored: could not match 'unique_ptr' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, unique_ptr<_Yp, _Dp> const& __p) ^ /usr/lib/llvm-9/bin/../include/c++/v1/ostream:1093:1: note: candidate template ignored: could not match 'bitset' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x) ^ /usr/lib/llvm-9/bin/../include/c++/v1/valarray:4165:1: note: candidate template ignored: substitution failure [with _Expr1 = std::__1::basic_ostream<char>, _Expr2 = std::__1::optional<int>]: no type named 'value_type' in 'std::__1::basic_ostream<char>' operator<<(const _Expr1& __x, const _Expr2& __y) ^ /usr/lib/llvm-9/bin/../include/c++/v1/valarray:4180:1: note: candidate template ignored: substitution failure [with _Expr = std::__1::basic_ostream<char>]: no type named 'value_type' in 'std::__1::basic_ostream<char>' operator<<(const _Expr& __x, const typename _Expr::value_type& __y) ^ /usr/lib/llvm-9/bin/../include/c++/v1/valarray:4196:1: note: candidate template ignored: requirement '__is_val_expr<std::__1::optional<int> >::value' was not satisfied [with _Expr = std::__1::optional<int>] operator<<(const typename _Expr::value_type& __x, const _Expr& __y) ^ /usr/lib/llvm-9/bin/../include/c++/v1/iomanip:362:1: note: candidate template ignored: could not match '__iom_t8' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t8<_MoneyT>& __x) ^ /usr/lib/llvm-9/bin/../include/c++/v1/iomanip:482:1: note: candidate template ignored: could not match '__iom_t10' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t10<_CharT>& __x) ^ /usr/lib/llvm-9/bin/../include/c++/v1/iomanip:572:33: note: candidate template ignored: could not match '__quoted_output_proxy' against 'optional' basic_ostream<_CharT, _Traits>& operator<<( ^ /usr/lib/llvm-9/bin/../include/c++/v1/iomanip:592:33: note: candidate template ignored: could not match '__quoted_proxy' against 'optional' basic_ostream<_CharT, _Traits>& operator<<( ^ /usr/lib/llvm-9/bin/../include/c++/v1/regex:5238:1: note: candidate template ignored: could not match 'sub_match' against 'optional' operator<<(basic_ostream<_CharT, _ST>& __os, const sub_match<_BiIter>& __m) ^ /usr/lib/llvm-9/bin/../include/c++/v1/random:1981:1: note: candidate template ignored: could not match 'linear_congruential_engine' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, ^ /usr/lib/llvm-9/bin/../include/c++/v1/random:2451:1: note: candidate template ignored: could not match 'mersenne_twister_engine' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, ^ /usr/lib/llvm-9/bin/../include/c++/v1/random:2772:1: note: candidate template ignored: could not match 'subtract_with_carry_engine' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, ^ /usr/lib/llvm-9/bin/../include/c++/v1/random:2954:1: note: candidate template ignored: could not match 'discard_block_engine' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, ^ /usr/lib/llvm-9/bin/../include/c++/v1/random:3207:1: note: candidate template ignored: could not match 'independent_bits_engine' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, ^ /usr/lib/llvm-9/bin/../include/c++/v1/random:3439:1: note: candidate template ignored: could not match 'shuffle_order_engine' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, ^ /usr/lib/llvm-9/bin/../include/c++/v1/random:3662:1: note: candidate template ignored: could not match 'uniform_int_distribution' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, ^ /usr/lib/llvm-9/bin/../include/c++/v1/random:3783:1: note: candidate template ignored: could not match 'uniform_real_distribution' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, ^ /usr/lib/llvm-9/bin/../include/c++/v1/random:4073:1: note: candidate template ignored: could not match 'binomial_distribution' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, ^ /usr/lib/llvm-9/bin/../include/c++/v1/random:4191:1: note: candidate template ignored: could not match 'exponential_distribution' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, ^ /usr/lib/llvm-9/bin/../include/c++/v1/random:4345:1: note: candidate template ignored: could not match 'normal_distribution' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, ^ /usr/lib/llvm-9/bin/../include/c++/v1/random:4495:1: note: candidate template ignored: could not match 'lognormal_distribution' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, ^ /usr/lib/llvm-9/bin/../include/c++/v1/random:4716:1: note: candidate template ignored: could not match 'poisson_distribution' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, ^ /usr/lib/llvm-9/bin/../include/c++/v1/random:4827:1: note: candidate template ignored: could not match 'weibull_distribution' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, ^ /usr/lib/llvm-9/bin/../include/c++/v1/random:4946:1: note: candidate template ignored: could not match 'extreme_value_distribution' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, ^ /usr/lib/llvm-9/bin/../include/c++/v1/random:5118:1: note: candidate template ignored: could not match 'gamma_distribution' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, ^ /usr/lib/llvm-9/bin/../include/c++/v1/random:5254:1: note: candidate template ignored: could not match 'negative_binomial_distribution' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, ^ /usr/lib/llvm-9/bin/../include/c++/v1/random:5360:1: note: candidate template ignored: could not match 'geometric_distribution' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, ^ /usr/lib/llvm-9/bin/../include/c++/v1/random:5464:1: note: candidate template ignored: could not match 'chi_squared_distribution' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, ^ /usr/lib/llvm-9/bin/../include/c++/v1/random:5584:1: note: candidate template ignored: could not match 'cauchy_distribution' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, ^ /usr/lib/llvm-9/bin/../include/c++/v1/random:5706:1: note: candidate template ignored: could not match 'fisher_f_distribution' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, ^ /usr/lib/llvm-9/bin/../include/c++/v1/random:5822:1: note: candidate template ignored: could not match 'student_t_distribution' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, ^ /usr/lib/llvm-9/bin/../include/c++/v1/random:6045:1: note: candidate template ignored: could not match 'discrete_distribution' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, ^ /usr/lib/llvm-9/bin/../include/c++/v1/random:6346:1: note: candidate template ignored: could not match 'piecewise_constant_distribution' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os, ^ /usr/lib/llvm-9/bin/../include/c++/v1/random:6685:1: note: candidate template ignored: could not match 'piecewise_linear_distribution' against 'optional' operator<<(basic_ostream<_CharT, _Traits>& __os,
-------------------------------------------
also got a reference from Float vs Double.