|
Boost : |
Subject: Re: [boost] [move] Implicit conversion to rvalues and move ctors.
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2014-08-28 03:07:11
Le 28/08/14 01:49, Mostafa a écrit :
> On Wed, 27 Aug 2014 16:17:06 -0700, Vicente J. Botet Escriba
> <vicente.botet_at_[hidden]> wrote:
>
>> Le 26/08/14 02:59, Mostafa a écrit :
>>> Here's another use case that fails to compile in C++03 but compiles
>>> successfully in C++11. (Note, it fails to compile in VS2005 and g++
>>> 4.8.2 -std=c++98, and compiles successfully with g++ 4.8.2 -std=c++11)
>>>
>>> MOC is a BOOST_MOVABLE_BUT_NOT_COPYABLE type. Foo is an empty with
>>> an implicit conversion function to MOC. "MOC m(Foo());" compiles
>>> successfully but "MOC m2(makeFoo());" fails to compile. Is this a
>>> bug or a limitation of Boost.Move in C++03?
>>>
>>> //----------
>>> //Start Code
>>> //----------
>>>
>>> #include <boost/move/core.hpp>
>>> #include <boost/move/utility.hpp>
>>>
>>> struct MOC
>>> {
>>> MOC() : value(121) {}
>>> MOC(BOOST_RV_REF(MOC) rhs) : value(rhs.value) {}
>>> int value;
>>> private:
>>> BOOST_MOVABLE_BUT_NOT_COPYABLE(MOC)
>>> };
>>>
>>> struct Foo
>>> {
>>> operator MOC ()
>>> {
>>> return MOC();
>>> }
>>> };
>>>
>>> Foo makeFoo()
>>> {
>>> return Foo();
>>> }
>>>
>>> int main()
>>> {
>>> // (1) Successfully Compiles.
>>> MOC m(Foo());
>>>
>>> // (2) Fails to Compile.
>>> MOC m2(makeFoo());
>>>
>>> return 0;
>>> }
>>>
>> I'm getting
>>
>> ../example/lambda_future.cpp:32:8: warning: parentheses were
>> disambiguated as a function declaration [-Wvexing-parse]
>> MOC m(Foo());
>> ^~~~~~~
>> ../example/lambda_future.cpp:32:9: note: add a pair of parentheses to
>> declare a variable
>> MOC m(Foo());
>> ^
>> ( )
>>
>>
>>
>> After adding the parentheses I get
>> ../example/lambda_future.cpp:32:7: error: no matching constructor for
>> initialization of 'MOC'
>> MOC m((Foo()));
>> ^ ~~~~~~~
>
> Yes, you're right. That would explain the different compiler behaviors
> between (1) and (2). Adding double parenthesis to both (1) and (2) now
> gives me the same error messages in g++ 4.8.2 -std=c++98. But they
> both do compile under C++11 mode. FWIW, I have an internal workaround,
> I'm just wondering if this is another undocumented limitation of
> Boost.Move in C++98.
>
There is something specific to conversions and move semantics that seems
to don't work. return an rvalue :(
#include <boost/move/core.hpp>
#include <boost/move/utility.hpp>
struct Bar
{};
struct MOC
{
MOC() : value(121) {}
MOC(Bar) : value(122) {}
MOC(BOOST_RV_REF(MOC) rhs) : value(rhs.value) {}
int value;
private:
BOOST_MOVABLE_BUT_NOT_COPYABLE(MOC)
};
struct Foo
{
operator MOC () const
{
return MOC();
}
};
Foo makeFoo()
{
return Foo();
}
Bar makeBar()
{
return Bar();
}
MOC makeMOC()
{
return MOC();
}
void f(MOC) {}
void g(MOC&) {}
void h(MOC const&) {}
int main()
{
// (1) Fails to Compile..
//MOC m(Foo());
//MOC m((Foo()));
// (1a) Compile.
MOC m((Bar()));
// (2) Fails to Compile.
// MOC m2(makeFoo());
// (2a) Compiles.
MOC m3(makeMOC());
MOC m4(makeBar());
// (3) Compiles.
f(MOC());
// (3.a) Fails to Compile.
//f(Bar());
//f(Foo());
// (4) Compiles.
MOC x;
g(x);
// (4.a) Fails to Compile.
//Bar y;
//g(y);
//Foo z;
//g(z);
// (5) Fails to Compile.
//h(MOC()); // Normal is not MOC is not CopyConstructible
// (5.a) Compiles.
h(Bar()); // MOC is not Constructible from Bar
h(Foo()); // // Foo is convertible to MOC
return 0;
}
> (What's strange is that on my machine -Wall -pedantic doesn't even
> catch that MVPE you noted above.)
>
Here it is my cl
"/Users/viboes/clang/clang+llvm-3.2-x86_64-apple-darwin11/bin/clang++"
-x c++ -Wextra -Wno-long-long -Wunused-function -Wno-unused-value
-Wno-c99-extensions -Wno-variadic-macros -O0 -g -O0 -fno-inline -Wall -g
-DBOOST_ALL_NO_LIB=1 -DBOOST_CHRONO_STATIC_LINK=1
-DBOOST_SYSTEM_NO_DEPRECATED -DBOOST_SYSTEM_STATIC_LINK=1
-DBOOST_THREAD_BUILD_LIB=1 -DBOOST_THREAD_POSIX
-DBOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
-DBOOST_THREAD_USE_LIB=1 -I"../../.." -c -o
"../../../bin.v2/libs/thread/test/ex_lambda_future2_lib.test/clang-darwin-3.2/debug/threading-multi/lambda_future.o"
"../example/lambda_future.cpp"
Vicente
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk