I have base object called IList
. Then I have VectorList
, that inherits IList
.
then I have function like this:
std::unique_ptr<IList> factory(){
auto vlist = std::make_unique<VectorList>();
return vlist;
}
This compiles without problem under gcc
, but clang
gives following error:
test_file.cc:26:9: error: no viable conversion from 'unique_ptr<VectorList, default_delete<VectorList>>' to
'unique_ptr<IList, default_delete<IList>>'
return vlist;
How is proper way to handle this kind of errors?
It appears (your version of) Clang is still following C++11 behaviour in this regard. In C++11, you had to use std::move
in this case, because the type of vlist
is different from the return type, and so the clause of "when returning an lvalue, try it as an rvalue first" did not apply.
In C++14, this restriction of "same types required" was lifted, and so in C++14, you shouldn't need the std::move
in the return statement. But if you need your code to compile with your current toolchain, simply add it there:
return std::move(vlist);
The exact C++11 wording was this:
12.8/32 When the criteria for elision of a copy operation are met or would be met save for the fact that the source
object is a function parameter, and the object to be copied is designated by an lvalue, overload resolution to
select the constructor for the copy is first performed as if the object were designated by an rvalue. ...
The criteria for copy elision (which include "same type") have to be met; they're just slightly extended to cover parameters as well.
In C++14 (N4140), the wording is broader:
12.8/32 When the criteria for elision of a copy/move operation are met, but not for an exception-declaration, and the
object to be copied is designated by an lvalue, or when the expression in a return
statement is a (possibly
parenthesized) id-expression that names an object with automatic storage duration declared in the body or
parameter-declaration-clause of the innermost enclosing function or lambda-expression, overload resolution
to select the constructor for the copy is first performed as if the object were designated by an rvalue.
(Emphasis mine)
As you can see, copy elision criteria are no longer required for the return
case.