I am working on pretty complex program and I need to initialize std::map variable of type std::map<int, std::vector<std::vector<std::array<std::byte, 2>>>> as const variable to do some comparison later. I tried to do it like this:
const std::vector<std::vector<std::array<std::byte, 2>>>
boundaries_length_one = {{{std::byte('\x00'), std::byte('\x7f')}}};
const std::vector<std::vector<std::array<std::byte, 2>>>
boundaries_length_two = {{{std::byte('\xc2'), std::byte('\xdf')}, {std::byte('\x80'), std::byte('\xbf')}}};
const std::vector<std::vector<std::array<std::byte, 2>>> boundaries_length_three = {
{{std::byte('\xe0'), nullptr}, {std::byte('\xa0'), std::byte('\xbf')}, {std::byte('\x80'), std::byte('\xbf')}},
{{std::byte('\xe1'), std::byte('\xec')}, {std::byte('\x80'), std::byte('\xbf')},
{std::byte('\x80'), std::byte('\xbf')}},
{{std::byte('\xe0'), nullptr}, {std::byte('\x80'), std::byte('\x9f')}, {std::byte('\x80'), std::byte('\xbf')}},
{{std::byte('\xee'), std::byte('\xef')}, {std::byte('\x80'), std::byte('\xbf')},
{std::byte('\x80'), std::byte('\xbf')}}
};
const std::vector<std::vector<std::array<std::byte, 2>>> boundaries_length_four = {
{{std::byte('\xf0'), nullptr}, {std::byte('\x90'), std::byte('\xbf')}, {std::byte('\x80'), std::byte('\xbf')},
{std::byte('\x80'), std::byte('\xbf')}},
{{std::byte('\xf1'), std::byte('\xf3')}, {std::byte('\x80'), std::byte('\xbf')},
{std::byte('\x80'), std::byte('\xbf')}, {std::byte('\x80'), std::byte('\xbf')}},
{{std::byte('\xf4'), nullptr}, {std::byte('\x80'), std::byte('\x8f')}, {std::byte('\x80'), std::byte('\xbf')},
{std::byte('\x80'), std::byte('\xbf')}}
};
std::map<int, const std::vector<std::vector<std::array<std::byte, 2>>>> boundaries = {
{1, boundaries_length_one},
{2, boundaries_length_two},
{3, boundaries_length_three},
{4, boundaries_length_four}};
The code above is located in separate namepace.
And unfortunately, I got this error:
In file included from /Users/denisivanenko/CLionProjects/UnicodeProcessorCpp/utf8.cpp:5:
/Users/denisivanenko/CLionProjects/UnicodeProcessorCpp/utf8.h:63:58: error: no matching constructor for initialization of 'const std::vector<std::vector<std::array<std::byte, 2> > >'
const std::vector<std::vector<std::array<std::byte, 2>>> boundaries_length_three = {
^ ~
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:528:9: note: candidate template ignored: couldn't infer template argument '_InputIterator'
vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:542:9: note: candidate template ignored: couldn't infer template argument '_ForwardIterator'
vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a,
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:520:9: note: candidate constructor template not viable: requires 2 arguments, but 4 were provided
vector(_InputIterator __first,
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:535:9: note: candidate constructor template not viable: requires 2 arguments, but 4 were provided
vector(_ForwardIterator __first,
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:518:5: note: candidate constructor not viable: requires 3 arguments, but 4 were provided
vector(size_type __n, const value_type& __x, const allocator_type& __a);
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:515:14: note: candidate constructor not viable: requires 2 arguments, but 4 were provided
explicit vector(size_type __n, const allocator_type& __a);
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:517:5: note: candidate constructor not viable: requires 2 arguments, but 4 were provided
vector(size_type __n, const value_type& __x);
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:558:5: note: candidate constructor not viable: requires 2 arguments, but 4 were provided
vector(const vector& __x, const allocator_type& __a);
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:567:5: note: candidate constructor not viable: requires 2 arguments, but 4 were provided
vector(initializer_list<value_type> __il, const allocator_type& __a);
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:578:5: note: candidate constructor not viable: requires 2 arguments, but 4 were provided
vector(vector&& __x, const allocator_type& __a);
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:501:40: note: candidate constructor not viable: requires single argument '__a', but 4 arguments were provided
_LIBCPP_INLINE_VISIBILITY explicit vector(const allocator_type& __a)
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:513:14: note: candidate constructor not viable: requires single argument '__n', but 4 arguments were provided
explicit vector(size_type __n);
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:557:5: note: candidate constructor not viable: requires single argument '__x', but 4 arguments were provided
vector(const vector& __x);
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:564:5: note: candidate constructor not viable: requires single argument '__il', but 4 arguments were provided
vector(initializer_list<value_type> __il);
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:570:5: note: candidate constructor not viable: requires single argument '__x', but 4 arguments were provided
vector(vector&& __x)
^
Error was a bit longer, but note message everywhere is almost the same, only number of elements needed and provided differ.
Can anyone help me initialize such a complex structure? I use C++17, clang 11.0.3 and CMake 3.17.2.
I managed to fix it. The prolem was in nullptr`s I used in place of std::byte.
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 months ago.
Improve this question
Here is the full program.
I'm using clang 13 with -std=c++20 -stdlib=libc++.
The error message, not included here because it's extremely long, basically says that the compiler does not even consider the operator<< function I've included here (error is on the std::cerr line near the end of the snippet).
#include <iostream>
#include <string>
#include <unordered_map>
template<typename K, typename V, typename ...Args>
std::ostream& operator<<(std::ostream& os, std::unordered_map<K, V, Args...> const& o) noexcept
{
for (auto const& [k, v] : o)
os << " " << k << ": " << v;
return os;
}
namespace my_namespace
{
struct A
{
std::unordered_map<int, std::string> map{{1, "hello"}, {2, "goodbye"}};
};
A a;
}
int main()
{
std::cerr << my_namespace::a; // error is here
}
Here is the lengthy error message (sorry for not including it earlier):
file.cpp:25:15: error: invalid operands to binary expression ('std::ostream' (aka 'basic_ostream<char>') and 'A')
std::cerr << a;
~~~~~~~~~ ^ ~
/usr/lib/llvm-13/bin/../include/c++/v1/cstddef:141:3: note: candidate function template not viable: no known conversion from 'std::ostream' (aka 'basic_ostream<char>') to 'std::byte' for 1st argument
operator<< (byte __lhs, _Integer __shift) noexcept
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:748:1: note: candidate function template not viable: no known conversion from 'A' to 'char' for 2nd argument
operator<<(basic_ostream<_CharT, _Traits>& __os, char __cn)
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:781:1: note: candidate function template not viable: no known conversion from 'A' to 'char' for 2nd argument
operator<<(basic_ostream<char, _Traits>& __os, char __c)
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:788:1: note: candidate function template not viable: no known conversion from 'A' to 'signed char' for 2nd argument
operator<<(basic_ostream<char, _Traits>& __os, signed char __c)
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:795:1: note: candidate function template not viable: no known conversion from 'A' to 'unsigned char' for 2nd argument
operator<<(basic_ostream<char, _Traits>& __os, unsigned char __c)
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:809:1: note: candidate function template not viable: no known conversion from 'A' to 'const char *' for 2nd argument
operator<<(basic_ostream<_CharT, _Traits>& __os, const char* __strn)
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:855:1: note: candidate function template not viable: no known conversion from 'A' to 'const char *' for 2nd argument
operator<<(basic_ostream<char, _Traits>& __os, const char* __str)
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:862:1: note: candidate function template not viable: no known conversion from 'A' to 'const signed char *' for 2nd argument
operator<<(basic_ostream<char, _Traits>& __os, const signed char* __str)
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:870:1: note: candidate function template not viable: no known conversion from 'A' to 'const unsigned char *' for 2nd argument
operator<<(basic_ostream<char, _Traits>& __os, const unsigned char* __str)
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:1055:1: note: candidate function template not viable: no known conversion from 'A' to 'const std::error_code' for 2nd argument
operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __ec)
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:741:1: note: candidate template ignored: deduced conflicting types for parameter '_CharT' ('char' vs. 'A')
operator<<(basic_ostream<_CharT, _Traits>& __os, _CharT __c)
^
/usr/lib/llvm-13/bin/../include/c++/v1/__random/uniform_int_distribution.h:282:1: note: candidate template ignored: could not match 'uniform_int_distribution<type-parameter-0-2>' against 'A'
operator<<(basic_ostream<_CharT, _Traits>& __os,
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:802:1: note: candidate template ignored: could not match 'const _CharT *' against 'A'
operator<<(basic_ostream<_CharT, _Traits>& __os, const _CharT* __str)
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:1038:1: note: candidate template ignored: could not match 'basic_string<type-parameter-0-0, type-parameter-0-1, type-parameter-0-2>' against 'A'
operator<<(basic_ostream<_CharT, _Traits>& __os,
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:1046:1: note: candidate template ignored: could not match 'basic_string_view<type-parameter-0-0, type-parameter-0-1>' against 'A'
operator<<(basic_ostream<_CharT, _Traits>& __os,
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:1063:1: note: candidate template ignored: could not match 'shared_ptr<type-parameter-0-2>' against 'A'
operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p)
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:1082:1: note: candidate template ignored: could not match 'bitset<_Size>' against 'A'
operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x)
^
file.cpp:6:15: note: candidate template ignored: could not match 'unordered_map<type-parameter-0-0, type-parameter-0-1, type-parameter-0-2...>' against 'A'
std::ostream& operator<<(std::ostream& os, std::unordered_map<K, V, Args...> const& o) noexcept
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:1030:11: note: candidate template ignored: requirement 'integral_constant<bool, false>::value' was not satisfied [with _Stream = std::ostream &, _Tp = A]
_Stream&& operator<<(_Stream&& __os, const _Tp& __x)
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:1075:1: note: candidate template ignored: could not match 'unique_ptr<type-parameter-0-2, type-parameter-0-3>' against 'A'
operator<<(basic_ostream<_CharT, _Traits>& __os, unique_ptr<_Yp, _Dp> const& __p)
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:188:20: note: candidate function not viable: no known conversion from 'A' to 'std::ostream &(*)(std::ostream &)' for 1st argument
basic_ostream& operator<<(basic_ostream& (*__pf)(basic_ostream&))
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:192:20: note: candidate function not viable: no known conversion from 'A' to 'basic_ios<std::basic_ostream<char>::char_type, std::basic_ostream<char>::traits_type> &(*)(basic_ios<std::basic_ostream<char>::char_type, std::basic_ostream<char>::traits_type> &)' (aka 'basic_ios<char, std::char_traits<char>> &(*)(basic_ios<char, std::char_traits<char>> &)') for 1st argument
basic_ostream& operator<<(basic_ios<char_type, traits_type>&
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:197:20: note: candidate function not viable: no known conversion from 'A' to 'std::ios_base &(*)(std::ios_base &)' for 1st argument
basic_ostream& operator<<(ios_base& (*__pf)(ios_base&))
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:200:20: note: candidate function not viable: no known conversion from 'A' to 'bool' for 1st argument
basic_ostream& operator<<(bool __n);
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:201:20: note: candidate function not viable: no known conversion from 'A' to 'short' for 1st argument
basic_ostream& operator<<(short __n);
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:202:20: note: candidate function not viable: no known conversion from 'A' to 'unsigned short' for 1st argument
basic_ostream& operator<<(unsigned short __n);
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:203:20: note: candidate function not viable: no known conversion from 'A' to 'int' for 1st argument
basic_ostream& operator<<(int __n);
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:204:20: note: candidate function not viable: no known conversion from 'A' to 'unsigned int' for 1st argument
basic_ostream& operator<<(unsigned int __n);
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:205:20: note: candidate function not viable: no known conversion from 'A' to 'long' for 1st argument
basic_ostream& operator<<(long __n);
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:206:20: note: candidate function not viable: no known conversion from 'A' to 'unsigned long' for 1st argument
basic_ostream& operator<<(unsigned long __n);
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:207:20: note: candidate function not viable: no known conversion from 'A' to 'long long' for 1st argument
basic_ostream& operator<<(long long __n);
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:208:20: note: candidate function not viable: no known conversion from 'A' to 'unsigned long long' for 1st argument
basic_ostream& operator<<(unsigned long long __n);
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:209:20: note: candidate function not viable: no known conversion from 'A' to 'float' for 1st argument
basic_ostream& operator<<(float __f);
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:210:20: note: candidate function not viable: no known conversion from 'A' to 'double' for 1st argument
basic_ostream& operator<<(double __f);
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:211:20: note: candidate function not viable: no known conversion from 'A' to 'long double' for 1st argument
basic_ostream& operator<<(long double __f);
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:212:20: note: candidate function not viable: no known conversion from 'A' to 'const void *' for 1st argument; take the address of the argument with &
basic_ostream& operator<<(const void* __p);
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:213:20: note: candidate function not viable: no known conversion from 'A' to 'basic_streambuf<std::basic_ostream<char>::char_type, std::basic_ostream<char>::traits_type> *' (aka 'basic_streambuf<char, std::char_traits<char>> *') for 1st argument
basic_ostream& operator<<(basic_streambuf<char_type, traits_type>* __sb);
^
/usr/lib/llvm-13/bin/../include/c++/v1/ostream:216:20: note: candidate function not viable: no known conversion from 'A' to 'std::nullptr_t' (aka 'nullptr_t') for 1st argument
basic_ostream& operator<<(nullptr_t)
^
1 error generated.
You have provided operator<< for a wrong type there. You gave for the std::unordered_map not for the my_namespace::A. Hence, the compiler can not find a operator<< for my_namespace::A.
You need instead
namespace my_namespace
{
// ...
std::ostream& operator<<(std::ostream& os, A const& a) noexcept
// ^^^^^^^^^^^^
{
for (auto const& [k, v] : a.map)
os << " " << k << ": " << v;
return os;
}
}
See demo
You overload operator<< for std::unordered_map<int, std::string> but not my_namespace::A here.
One way is to overload it for my_namespace::A.
std::ostream& operator<<(std::ostream& os, const A& a) noexcept
{
for (auto const& [k, v] : a.map)
os << " " << k << ": " << v;
return os;
}
Another way is to make A can be implicitly converted to std::unordered_map<int, std::string>.
struct A
{
A() {}
std::unordered_map<int, std::string> map{{1, "hello"}, {2, "goodbye"}};
operator std::unordered_map<int, std::string>() const {
return map;
}
};
I want to declare my 2D vector first, then give it a size.
But why I am getting error?
Can anyone explain me?
int main() {
vector<vector<int>> a;
a = vector<int>(16, vector<int>(15));
cout << a.size() << a[0].size();
}
The reason for doing it is that I don't know the size before but after getting the input from the user, I want to give it the size.
Error:
Char 9: error: no matching constructor for initialization of 'vector<int>'
a = vector<int>(16, vector<int>(15));
^ ~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:507:7: note: candidate constructor not viable: no known conversion from 'vector<int>' to 'const std::vector<int, std::allocator<int>>::allocator_type' (aka 'const std::allocator<int>') for 2nd argument
vector(size_type __n, const allocator_type& __a = allocator_type())
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:519:7: note: candidate constructor not viable: no known conversion from 'vector<int>' to 'const std::vector<int, std::allocator<int>>::value_type' (aka 'const int') for 2nd argument
vector(size_type __n, const value_type& __value,
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:572:7: note: candidate constructor not viable: no known conversion from 'int' to 'const std::vector<int, std::allocator<int>>' for 1st argument
vector(const vector& __x, const allocator_type& __a)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:604:7: note: candidate constructor not viable: no known conversion from 'int' to 'std::vector<int, std::allocator<int>>' for 1st argument
vector(vector&& __rv, const allocator_type& __m)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:622:7: note: candidate constructor not viable: no known conversion from 'int' to 'initializer_list<std::vector<int, std::allocator<int>>::value_type>' (aka 'initializer_list<int>') for 1st argument
vector(initializer_list<value_type> __l,
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:650:2: note: candidate template ignored: deduced conflicting types for parameter '_InputIterator' ('int' vs. 'std::vector<int, std::allocator<int>>')
vector(_InputIterator __first, _InputIterator __last,
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:494:7: note: candidate constructor not viable: requires single argument '__a', but 2 arguments were provided
vector(const allocator_type& __a) _GLIBCXX_NOEXCEPT
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:550:7: note: candidate constructor not viable: requires single argument '__x', but 2 arguments were provided
vector(const vector& __x)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:569:7: note: candidate constructor not viable: requires 1 argument, but 2 were provided
vector(vector&&) noexcept = default;
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:582:7: note: candidate constructor not viable: requires 3 arguments, but 2 were provided
vector(vector&& __rv, const allocator_type& __m, true_type) noexcept
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:586:7: note: candidate constructor not viable: requires 3 arguments, but 2 were provided
vector(vector&& __rv, const allocator_type& __m, false_type)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:484:7: note: candidate constructor not viable: requires 0 arguments, but 2 were provided
vector() = default;
^
1 error generated.
vector<int> is not a 2D vector.
Instead of this:
a = vector<int>(16, vector<int>(15));
You should use this:
a = vector<vector<int>>(16, vector<int>(15));
I would expect that std::reference_wrapper would work as a reference in terms of converting non-const into const, like:
int a = 10;
int& refA = a;
const int& constRefA = refA;
The following code compiles and works fine in MSVC and GCC, but not on Clang. I just don't understand why, is it UB, or actually an issue on Clang compiler?
#include <functional>
#include <optional>
int main()
{
int a = 10;
std::reference_wrapper<int> ref = a;
std::reference_wrapper<const int> constRef = ref;
std::optional<std::reference_wrapper<int>> optRef = a;
std::optional<std::reference_wrapper<const int>> optConstRef = optRef;
return 0;
}
On Clang only, displays the following error:
prog.cc:13:39: error: no viable conversion from 'reference_wrapper<int>' to 'reference_wrapper<const int>'
std::reference_wrapper<const int> constRef = ref;
https://wandbox.org/permlink/FSY4tCvE9B17hbVn
prog.cc:13:39: error: no viable conversion from 'reference_wrapper<int>' to 'reference_wrapper<const int>'
std::reference_wrapper<const int> constRef = ref;
^ ~~~
/opt/wandbox/clang-head/include/c++/v1/__functional_base:374:28: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'std::reference_wrapper<int>' to 'const std::reference_wrapper<const int> &' for 1st argument
class _LIBCPP_TEMPLATE_VIS reference_wrapper
^
/opt/wandbox/clang-head/include/c++/v1/__functional_base:374:28: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'std::reference_wrapper<int>' to 'std::reference_wrapper<const int> &&' for 1st argument
/opt/wandbox/clang-head/include/c++/v1/__functional_base:386:5: note: candidate constructor not viable: no known conversion from 'std::reference_wrapper<int>' to 'std::reference_wrapper<const int>::type &' (aka 'const int &') for 1st argument
reference_wrapper(type& __f) _NOEXCEPT
^
/opt/wandbox/clang-head/include/c++/v1/__functional_base:389:14: note: candidate constructor not viable: no known conversion from 'std::reference_wrapper<int>' to 'std::reference_wrapper<const int>::type &&' (aka 'const int &&') for 1st argument
private: reference_wrapper(type&&); public: // = delete; // do not bind to temps
^
/opt/wandbox/clang-head/include/c++/v1/__functional_base:394:5: note: candidate function
operator type&() const _NOEXCEPT {return *__f_;}
^
prog.cc:16:54: error: no viable conversion from 'optional<reference_wrapper<int>>' to 'optional<reference_wrapper<const int>>'
std::optional<std::reference_wrapper<const int>> optConstRef = optRef;
^ ~~~~~~
/opt/wandbox/clang-head/include/c++/v1/optional:689:41: note: candidate constructor not viable: no known conversion from 'std::optional<std::reference_wrapper<int>>' to 'const std::optional<std::reference_wrapper<const int>> &' for 1st argument
_LIBCPP_INLINE_VISIBILITY constexpr optional(const optional&) = default;
^
/opt/wandbox/clang-head/include/c++/v1/optional:690:41: note: candidate constructor not viable: no known conversion from 'std::optional<std::reference_wrapper<int>>' to 'std::optional<std::reference_wrapper<const int>> &&' for 1st argument
_LIBCPP_INLINE_VISIBILITY constexpr optional(optional&&) = default;
^
/opt/wandbox/clang-head/include/c++/v1/optional:691:41: note: candidate constructor not viable: no known conversion from 'std::optional<std::reference_wrapper<int>>' to 'std::nullopt_t' for 1st argument
_LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
^
/opt/wandbox/clang-head/include/c++/v1/optional:715:15: note: candidate template ignored: substitution failure [with _Up = std::optional<std::reference_wrapper<int>> &]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
constexpr optional(_Up&& __v)
^
/opt/wandbox/clang-head/include/c++/v1/optional:730:5: note: candidate template ignored: substitution failure [with _Up = std::reference_wrapper<int>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
optional(const optional<_Up>& __v)
^
/opt/wandbox/clang-head/include/c++/v1/optional:748:5: note: candidate template ignored: substitution failure [with _Up = std::reference_wrapper<int>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
optional(optional<_Up>&& __v)
^
/opt/wandbox/clang-head/include/c++/v1/optional:701:24: note: explicit constructor is not a candidate
constexpr explicit optional(_InPlaceT, _Args&&... __args)
^
/opt/wandbox/clang-head/include/c++/v1/optional:722:24: note: explicit constructor is not a candidate
constexpr explicit optional(_Up&& __v)
^
/opt/wandbox/clang-head/include/c++/v1/optional:738:14: note: explicit constructor is not a candidate
explicit optional(const optional<_Up>& __v)
^
/opt/wandbox/clang-head/include/c++/v1/optional:756:14: note: explicit constructor is not a candidate
explicit optional(optional<_Up>&& __v)
^
2 errors generated.
The std library you are using on wandbox has a bug. It only found 2 constructors and a conversion operator.
Compilers and standard libraries are not always in sync.
printf("Hello World");
int a = 10;
std::reference_wrapper<int> ref = a;
std::reference_wrapper<const int> constRef( ref );
std::optional<std::reference_wrapper<int>> optRef = a;
std::optional<std::reference_wrapper<const int>> optConstRef( optRef );
return 0;
By making the conversions explicit it works. I don't know why; there aren't any explicit conversions differences in my reading of reference_wrapper construction and conversion operators.
But the lack of implicit reference wrapping conversion would explain why the optional would want it.
In any case, this is clearly a bug. The universal conversion constructor for reference_wrapper<const int> should apply if:
void FUN(int const&) {}
FUN(ref)
overload resolution works, and it does for a reference_wrapper<int>.
So in general this is more of a theoretical language lawyer question, than an actual one. While fighting with template with obscure template error, I found a behavior I could not explain with clang (bottom line - no warning that I am trying to move a class that is not movable). The weird thing is that the behaviour with clang changes depending on whether -std=c++17 is present or not.
So here is the MVP of the issue:
#include <utility>
struct INoLikeToMoveIt
{
INoLikeToMoveIt() = default;
INoLikeToMoveIt(const INoLikeToMoveIt&) = delete;
INoLikeToMoveIt(INoLikeToMoveIt&&) = delete;
INoLikeToMoveIt& operator=(const INoLikeToMoveIt&) = delete;
INoLikeToMoveIt& operator=(INoLikeToMoveIt&&) = delete;
};
int main()
{
INoLikeToMoveIt a, b;
auto c = std::make_pair(std::move(a), std::move(b));
return 0;
}
Obviously this will not work (but since in the actual case the non movable class was a member of a parent class hidden deep in the sources, w/o any warnings that it is not movable I could not immediately understand what is going on). So taking this example on godbolt with -std=c+=17 gives:
n file included from <source>:1:
In file included from /opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/utility:70:
/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:529:14: error: no matching constructor for initialization of '__pair_type' (aka 'pair<INoLikeToMoveIt, INoLikeToMoveIt>')
return __pair_type(std::forward<_T1>(__x), std::forward<_T2>(__y));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:15:19: note: in instantiation of function template specialization 'std::make_pair<INoLikeToMoveIt, INoLikeToMoveIt>' requested here
auto c = std::make_pair(std::move(a), std::move(b));
^
/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:260:17: note: candidate template ignored: requirement '_PCC<true, INoLikeToMoveIt, INoLikeToMoveIt>::_ConstructiblePair()' was not satisfied [with _U1 = INoLikeToMoveIt, _U2 = INoLikeToMoveIt]
constexpr pair(const _T1& __a, const _T2& __b)
^
/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:269:26: note: candidate template ignored: requirement '_PCC<true, INoLikeToMoveIt, INoLikeToMoveIt>::_ConstructiblePair()' was not satisfied [with _U1 = INoLikeToMoveIt, _U2 = INoLikeToMoveIt]
explicit constexpr pair(const _T1& __a, const _T2& __b)
^
/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:311:18: note: candidate template ignored: requirement '_PCC<true, INoLikeToMoveIt, INoLikeToMoveIt>::_MoveCopyPair()' was not satisfied [with _U1 = INoLikeToMoveIt]
constexpr pair(_U1&& __x, const _T2& __y)
^
/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:318:27: note: candidate template ignored: requirement '_PCC<true, INoLikeToMoveIt, INoLikeToMoveIt>::_MoveCopyPair()' was not satisfied [with _U1 = INoLikeToMoveIt]
explicit constexpr pair(_U1&& __x, const _T2& __y)
^
/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:325:18: note: candidate template ignored: requirement '_PCC<true, INoLikeToMoveIt, INoLikeToMoveIt>::_CopyMovePair()' was not satisfied [with _U2 = INoLikeToMoveIt]
constexpr pair(const _T1& __x, _U2&& __y)
^
/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:332:17: note: candidate template ignored: requirement '_PCC<true, INoLikeToMoveIt, INoLikeToMoveIt>::_CopyMovePair()' was not satisfied [with _U2 = INoLikeToMoveIt]
explicit pair(const _T1& __x, _U2&& __y)
^
/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:341:12: note: candidate template ignored: requirement '_PCC<true, INoLikeToMoveIt, INoLikeToMoveIt>::_MoveConstructiblePair()' was not satisfied [with _U1 = INoLikeToMoveIt, _U2 = INoLikeToMoveIt]
constexpr pair(_U1&& __x, _U2&& __y)
^
/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:350:21: note: candidate template ignored: requirement '_PCC<true, INoLikeToMoveIt, INoLikeToMoveIt>::_MoveConstructiblePair()' was not satisfied [with _U1 = INoLikeToMoveIt, _U2 = INoLikeToMoveIt]
explicit constexpr pair(_U1&& __x, _U2&& __y)
^
/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:229:26: note: candidate constructor template not viable: requires 0 arguments, but 2 were provided
_GLIBCXX_CONSTEXPR pair()
^
/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:242:26: note: candidate constructor template not viable: requires 0 arguments, but 2 were provided
explicit constexpr pair()
^
/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:291:19: note: candidate constructor template not viable: requires single argument '__p', but 2 arguments were provided
constexpr pair(const pair<_U1, _U2>& __p)
^
/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:300:21: note: candidate constructor template not viable: requires single argument '__p', but 2 arguments were provided
explicit constexpr pair(const pair<_U1, _U2>& __p)
^
/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:360:12: note: candidate constructor template not viable: requires single argument '__p', but 2 arguments were provided
constexpr pair(pair<_U1, _U2>&& __p)
^
/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:370:21: note: candidate constructor template not viable: requires single argument '__p', but 2 arguments were provided
explicit constexpr pair(pair<_U1, _U2>&& __p)
^
/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:375:9: note: candidate constructor template not viable: requires 3 arguments, but 2 were provided
pair(piecewise_construct_t, tuple<_Args1...>, tuple<_Args2...>);
^
/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:436:9: note: candidate constructor template not viable: requires 4 arguments, but 2 were provided
pair(tuple<_Args1...>&, tuple<_Args2...>&,
^
/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:303:17: note: candidate constructor not viable: requires 1 argument, but 2 were provided
constexpr pair(const pair&) = default;
^
1 error generated.
Compiler returned: 1
which I would interpret as "hey I'm gonna tell you why you can't all the stuff you actually don't want, but not that the move ctor is deleted". Once I change -std=c++14 the same diagnostic but with a trailing lines:
<source>:15:10: error: call to implicitly-deleted copy constructor of 'std::pair<INoLikeToMoveIt, INoLikeToMoveIt>'
auto c = std::make_pair(std::move(a), std::move(b));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:303:17: note: explicitly defaulted function was implicitly deleted here
constexpr pair(const pair&) = default;
^
/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_pair.h:214:11: note: copy constructor of 'pair<INoLikeToMoveIt, INoLikeToMoveIt>' is implicitly deleted because field 'first' has a deleted copy constructor
_T1 first; /// #c first is a copy of the first object
^
<source>:6:5: note: 'INoLikeToMoveIt' has been explicitly marked deleted here
INoLikeToMoveIt(const INoLikeToMoveIt&) = delete;
^
2 errors generated.
Compiler returned: 1
which is still does not mention the deleted move c-tor, but at least points me to culprit. Initially I though, hey, maybe there is a new overload/semantics for std::make_pair that would cause this, but looking at std::make_pair does not show any C++17 relevant changes. So is this just a weird behaviour in diagnostics or is there an explanation for this? Just curios.
When compiling my program with clang++ --std=c++11 file.cpp the line std::unique_ptr<FILE> pipe(popen(cmd.c_str(), "r"), pclose); throws the error
memdiff.cpp:11:27: error: no matching constructor for initialization of
'std::unique_ptr<FILE>'
std::unique_ptr<FILE> pipe(popen(cmd.c_str(), "r"), pclose);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:2530:31: note:
candidate constructor not viable: no known conversion from 'int (FILE *)'
to 'const std::__1::default_delete<__sFILE>' for 2nd argument
_LIBCPP_INLINE_VISIBILITY unique_ptr(pointer __p, typename conditional<
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:2537:31: note:
candidate constructor not viable: no known conversion from 'int (FILE *)'
to 'typename remove_reference<deleter_type>::type' (aka
'std::__1::default_delete<__sFILE>') for 2nd argument
_LIBCPP_INLINE_VISIBILITY unique_ptr(pointer __p, typename remove_ref...
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:2547:9: note:
candidate template ignored: could not match 'unique_ptr<type-parameter-0-0,
type-parameter-0-1>' against '__sFILE *'
unique_ptr(unique_ptr<_Up, _Ep>&& __u,
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:2562:35: note:
candidate template ignored: could not match 'auto_ptr<type-parameter-0-0>'
against '__sFILE *'
_LIBCPP_INLINE_VISIBILITY unique_ptr(auto_ptr<_Up>&& __p,
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:2516:49: note:
candidate constructor not viable: requires 1 argument, but 2 were provided
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:2522:40: note:
candidate constructor not viable: requires single argument '__p', but 2
arguments were provided
_LIBCPP_INLINE_VISIBILITY explicit unique_ptr(pointer __p) _NOEXCEPT
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:2543:31: note:
candidate constructor not viable: requires single argument '__u', but 2
arguments were provided
_LIBCPP_INLINE_VISIBILITY unique_ptr(unique_ptr&& __u) _NOEXCEPT
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:2487:29: note:
candidate constructor (the implicit copy constructor) not viable: requires
1 argument, but 2 were provided
class _LIBCPP_TYPE_VIS_ONLY unique_ptr
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:2510:49: note:
candidate constructor not viable: requires 0 arguments, but 2 were provided
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT
^
1 error generated.
If I switch from a unique_ptr to a shared_ptr my program compiles. Why does one constructor work and one not, and how do I fix it?
As correctly pointed out in the first comment: With unique_ptr, the type of the deleter must be specified as the second template parameter.
However, it's supposed to be a function pointer:
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose);