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);
Related
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.
I have been trying to create a unique_ptr, and then move it into a vector of that pointer with push_back(). When I try to do this, I get a long compilation error. I have read multiple questions on this subject, including the section on "Containers of unique_ptr" here: https://eli.thegreenplace.net/2012/06/20/c11-using-unique_ptr-with-standard-library-containers
As well as this StackOverflow question: Why can I not push_back a unique_ptr into a vector?
This is a tiny sample program that will not compile:
// ptrtest.cpp
#include <memory>
#include <vector>
class TestObject{
public:
TestObject(int data): data(data){}
int getData(){return data;}
private:
int data;
};
using namespace std;
int main (int argc, char* argv[]){
vector<unique_ptr<TestObject> > v;
unique_ptr<TestObject> obj = unique_ptr<TestObject>(new TestObject(5));
v.push_back(move(obj));
return 0;
}
This is the compiler error the program gives me:
$ clang++ ptrtest.cpp -otest
In file included from ptrtest.cpp:1:
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1574:36: error:
no matching constructor for initialization of
'std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> >'
::new ((void*)__p) _Tp(__a0);
^ ~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/vector:1593:25: note: in
instantiation of function template specialization
'std::__1::allocator_traits<std::__1::allocator<std::__1::unique_ptr<TestObject,
std::__1::default_delete<TestObject> > >
>::construct<std::__1::unique_ptr<TestObject,
std::__1::default_delete<TestObject> >, std::__1::unique_ptr<TestObject,
std::__1::default_delete<TestObject> > >' requested here
__alloc_traits::construct(this->__alloc(),
^
ptrtest.cpp:16:4: note: in instantiation of member function
'std::__1::vector<std::__1::unique_ptr<TestObject,
std::__1::default_delete<TestObject> >,
std::__1::allocator<std::__1::unique_ptr<TestObject,
std::__1::default_delete<TestObject> > > >::push_back' requested here
v.push_back(move(obj));
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:2482:3: note:
candidate constructor not viable: 1st argument ('const
std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> >')
would lose const qualifier
unique_ptr(unique_ptr&);
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:2498:3: note:
candidate constructor not viable: no known conversion from 'const
std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> >'
to 'std::__1::nullptr_t' for 1st argument
unique_ptr(nullptr_t) : __ptr_(pointer())
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:2504:12: note:
candidate constructor not viable: no known conversion from 'const
std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> >'
to 'std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject>
>::pointer' (aka 'TestObject *') for 1st argument
explicit unique_ptr(pointer __p)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:2516:3: note:
candidate constructor not viable: no known conversion from 'const
std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> >'
to '__rv<std::__1::unique_ptr<TestObject,
std::__1::default_delete<TestObject> > >' for 1st argument
unique_ptr(__rv<unique_ptr> __u)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:2483:35: note:
candidate template ignored: deduced type 'unique_ptr<...>' of 1st
parameter does not match adjusted type 'const unique_ptr<...>' of
argument [with _Up = TestObject, _Ep =
std::__1::default_delete<TestObject>]
template <class _Up, class _Ep> unique_ptr(unique_ptr<_Up, _Ep>&);
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:2490:3: note:
candidate constructor not viable: requires 0 arguments, but 1 was provided
unique_ptr() : __ptr_(pointer())
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:2535:3: note:
candidate constructor not viable: requires 2 arguments, but 1 was provided
unique_ptr(pointer __p, deleter_type __d)
^
In file included from ptrtest.cpp:2:
/Library/Developer/CommandLineTools/usr/include/c++/v1/vector:1580:21: error:
no matching member function for call to 'construct'
__alloc_traits::construct(__a, _VSTD::__to_raw_pointer(__v.__end_), ...
~~~~~~~~~~~~~~~~^~~~~~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/vector:1599:9: note: in
instantiation of function template specialization
'std::__1::vector<std::__1::unique_ptr<TestObject,
std::__1::default_delete<TestObject> >,
std::__1::allocator<std::__1::unique_ptr<TestObject,
std::__1::default_delete<TestObject> > > >::__push_back_slow_path<const
std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> > >'
requested here
__push_back_slow_path(__x);
^
ptrtest.cpp:16:4: note: in instantiation of member function
'std::__1::vector<std::__1::unique_ptr<TestObject,
std::__1::default_delete<TestObject> >,
std::__1::allocator<std::__1::unique_ptr<TestObject,
std::__1::default_delete<TestObject> > > >::push_back' requested here
v.push_back(move(obj));
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1572:21: note:
candidate template ignored: substitution failure [with _Tp =
std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> >,
_A0 = std::__1::unique_ptr<TestObject,
std::__1::default_delete<TestObject> >]
static void construct(allocator_type&, _Tp* __p, const _A0& __a0)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1566:21: note:
candidate function template not viable: requires 2 arguments, but 3 were
provided
static void construct(allocator_type&, _Tp* __p)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1578:21: note:
candidate function template not viable: requires 4 arguments, but 3 were
provided
static void construct(allocator_type&, _Tp* __p, const _A0& __a0,
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1585:21: note:
candidate function template not viable: requires 5 arguments, but 3 were
provided
static void construct(allocator_type&, _Tp* __p, const _A0& __a0,
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1677:17: error:
use of undeclared identifier 'construct'
construct(__a, _VSTD::__to_raw_pointer(__end2-1), _VSTD:...
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/vector:898:21: note: in
instantiation of function template specialization
'std::__1::allocator_traits<std::__1::allocator<std::__1::unique_ptr<TestObject,
std::__1::default_delete<TestObject> > >
>::__construct_backward<std::__1::unique_ptr<TestObject,
std::__1::default_delete<TestObject> > *>' requested here
__alloc_traits::__construct_backward(this->__alloc(), this->__begin_...
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/vector:1582:5: note: in
instantiation of member function
'std::__1::vector<std::__1::unique_ptr<TestObject,
std::__1::default_delete<TestObject> >,
std::__1::allocator<std::__1::unique_ptr<TestObject,
std::__1::default_delete<TestObject> > > >::__swap_out_circular_buffer'
requested here
__swap_out_circular_buffer(__v);
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/vector:1599:9: note: in
instantiation of function template specialization
'std::__1::vector<std::__1::unique_ptr<TestObject,
std::__1::default_delete<TestObject> >,
std::__1::allocator<std::__1::unique_ptr<TestObject,
std::__1::default_delete<TestObject> > > >::__push_back_slow_path<const
std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> > >'
requested here
__push_back_slow_path(__x);
^
ptrtest.cpp:16:4: note: in instantiation of member function
'std::__1::vector<std::__1::unique_ptr<TestObject,
std::__1::default_delete<TestObject> >,
std::__1::allocator<std::__1::unique_ptr<TestObject,
std::__1::default_delete<TestObject> > > >::push_back' requested here
v.push_back(move(obj));
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1566:21: note:
must qualify identifier to find this declaration in dependent base class
static void construct(allocator_type&, _Tp* __p)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1572:21: note:
must qualify identifier to find this declaration in dependent base class
static void construct(allocator_type&, _Tp* __p, const _A0& __a0)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1578:21: note:
must qualify identifier to find this declaration in dependent base class
static void construct(allocator_type&, _Tp* __p, const _A0& __a0,
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1585:21: note:
must qualify identifier to find this declaration in dependent base class
static void construct(allocator_type&, _Tp* __p, const _A0& __a0,
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1677:17: error:
no matching function for call to 'construct'
construct(__a, _VSTD::__to_raw_pointer(__end2-1), _VSTD:...
^~~~~~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1572:21: note:
candidate template ignored: substitution failure [with _Tp =
std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> >,
_A0 = std::__1::unique_ptr<TestObject,
std::__1::default_delete<TestObject> >]
static void construct(allocator_type&, _Tp* __p, const _A0& __a0)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1566:21: note:
candidate function template not viable: requires 2 arguments, but 3 were
provided
static void construct(allocator_type&, _Tp* __p)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1578:21: note:
candidate function template not viable: requires 4 arguments, but 3 were
provided
static void construct(allocator_type&, _Tp* __p, const _A0& __a0,
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1585:21: note:
candidate function template not viable: requires 5 arguments, but 3 were
provided
static void construct(allocator_type&, _Tp* __p, const _A0& __a0,
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1677:17: error:
no matching function for call to 'construct'
construct(__a, _VSTD::__to_raw_pointer(__end2-1), _VSTD:...
^~~~~~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1572:21: note:
candidate template ignored: substitution failure [with _Tp =
std::__1::unique_ptr<TestObject, std::__1::default_delete<TestObject> >,
_A0 = std::__1::unique_ptr<TestObject,
std::__1::default_delete<TestObject> >]
static void construct(allocator_type&, _Tp* __p, const _A0& __a0)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1578:21: note:
candidate function template not viable: requires 4 arguments, but 3 were
provided
static void construct(allocator_type&, _Tp* __p, const _A0& __a0,
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1585:21: note:
candidate function template not viable: requires 5 arguments, but 3 were
provided
static void construct(allocator_type&, _Tp* __p, const _A0& __a0,
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/memory:1566:21: note:
candidate function template not viable: requires 2 arguments, but 3 were
provided
static void construct(allocator_type&, _Tp* __p)
^
5 errors generated.
My compiler is clang++ and I'm running macOS 10.14.3.
Are you sure you are using c++11?
Prior to c++11 the signature for push_back(...) was:
void push_back (const value_type& val);
So even if you give a temporary it will still use the copy constructor.
In C++11 there is an overload to handle the use of temporary variables to move instead of copy.
Either way, you should consider using .emplace_back(...). This was specifically made for handling temporaries and inline constructing the object so there is no copy.
The following code compiles with g++ -std=c++11 but not with clang++ -std=c++11.
Questions
What is the meaning of the single colon "operator" in this context?
Clarification/Edit: How does GCC interpret the code?
How can I make GCC not compile this code? (Assuming that Clang follows the C++ Standard here.) Is there a flag for this?
Code
Compile with g++ -std=c++11 main.cpp and clang++ -std=c++11 main.cpp. I am using GCC 4.8 and Clang 6.0.0 (trunk).
#include <iostream>
#include <vector>
enum Dir { LEFT, RIGHT };
int main(int argc, char** argv) {
// Interesting line: Notice the single ':'
std::vector<Dir> dirs = { Dir:LEFT, Dir:RIGHT };
for (auto v: dirs) {
std::cout << v << std::endl;
}
return 0;
}
Clang Error Message
For completeness and search-ability:
$ clang++ -std=c++11 main.cpp
main.cpp:7:29: warning: use of GNU old-style field designator extension [-Wgnu-designator]
std::vector<Dir> dirs = { Dir:LEFT, Dir:RIGHT };
^~~~
.Dir =
main.cpp:7:39: warning: use of GNU old-style field designator extension [-Wgnu-designator]
std::vector<Dir> dirs = { Dir:LEFT, Dir:RIGHT };
^~~~
.Dir =
main.cpp:7:20: error: no matching constructor for initialization of 'std::vector<Dir>'
std::vector<Dir> dirs = { Dir:LEFT, Dir:RIGHT };
^ ~~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:269:7: note: candidate constructor not viable: cannot convert argument of incomplete type 'void' to 'std::vector::size_type' (aka 'unsigned long') for 1st argument
vector(size_type __n, const allocator_type& __a = allocator_type())
^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:281:7: note: candidate constructor not viable: cannot convert argument of incomplete type 'void' to 'std::vector::size_type' (aka 'unsigned long') for 1st argument
vector(size_type __n, const value_type& __value,
^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:331:7: note: candidate constructor not viable: cannot convert argument of incomplete type 'void' to 'const std::vector<Dir, std::allocator<Dir> >' for 1st argument
vector(const vector& __x, const allocator_type& __a)
^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:340:7: note: candidate constructor not viable: cannot convert argument of incomplete type 'void' to 'std::vector<Dir, std::allocator<Dir> >' for 1st argument
vector(vector&& __rv, const allocator_type& __m)
^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:364:7: note: candidate constructor not viable: cannot convert argument of incomplete type 'void' to 'initializer_list<std::vector<Dir, std::allocator<Dir> >::value_type>'
(aka 'initializer_list<Dir>') for 1st argument
vector(initializer_list<value_type> __l,
^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:392:9: note: candidate template ignored: substitution failure [with _InputIterator = void]: no type named 'iterator_category' in 'std::iterator_traits<void>'
vector(_InputIterator __first, _InputIterator __last,
^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:256:7: note: candidate constructor not viable: requires single argument '__a', but 2 arguments were provided
vector(const allocator_type& __a)
^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:310:7: note: candidate constructor not viable: requires single argument '__x', but 2 arguments were provided
vector(const vector& __x)
^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:327:7: note: candidate constructor not viable: requires single argument '__x', but 2 arguments were provided
vector(vector&& __x) noexcept
^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_vector.h:248:7: note: candidate constructor not viable: requires 0 arguments, but 2 were provided
vector()
^
2 warnings and 1 error generated.
To cause gcc to reject the code, use -pedantic switch.
The colon is an extension in GNU mode: X:Y means .X = Y, which is a designated initializer. (Neither of these are supported in ISO C++).
gcc also accepts the following code:
std::vector<int> v = { .a = 1, .b = 2 };
but rejects the code:
struct S { int p, q; S() {} };
S s = { .a = 1, .b = 2 }; // S has no member named 'a'
I guess this is a compiler bug; something about initializing a std::vector<int> causes it to ignore the names of the designated initializers. Note, this sort of thing is a hallmark of non-standard features: often the very reason they aren't in the standard is that they didn't mix well with other language features and nobody could come up with a sensible proposal to handle all possible cases.