Re: [Boost-users] boost::variant & c++11

2013/5/15 Bryan Catanzaro <bcatanzaro@acm.org>:
Hi Antony - Perhaps it is compiler dependent. Which version of MSVC did you reproduce the error with? Does that version have c++11 support enabled (in particular, rvalue references) As I said, with Boost 1.48.0, this code works with g++ 4.6 and 4.7. With 1.53.0, it works with g++ 4.6 and 4.7 only if c++11 support is turned off. If c++11 support is turned on, the code does not work. I've attached a shell script that compiles the attached code with the cross product of {(g++4.6, g++4.7), (boost1.48, boost1.53), (noc++11, yesc++11)}. As you can see from test.txt, the error happens only with boost 1.53 and c++11 support.
- bryan
Exactly the same things happen on GCC-4.5 and Clang-3.0. But what is more interesting here: convertible c; const convertible& cc = c; // Always compiles, using any flags, compiler and Boost version my_variant y = cc; my_variant y1 = static_cast<const convertible&>(c); my_variant y2 = static_cast<const convertible>(c); // Always fail to compile, using any flags and Boost version // my_variant z = c; // my_variant y3 = static_cast<convertible&>(c); Tested on clang, gcc4.5, gcc 4.6, gcc4.7 on Boost 1.48 and Boost 1.53 with and without C++11 flags. If we modify `convertible`: struct convertible { operator my_variant() { return my_variant(); } operator my_variant() const { return my_variant(); } }; Then ALL the tests pass well, even the commented out ones. Even `my_variant y4 = static_cast<convertible&&>(c);` works well. I'll test it tomorrow on Visual Studio 11 once more and investigate issue futher. -- Best regards, Antony Polukhin

Thanks for taking a look. I checked, and on my system, you're right: adding a non-const conversion operator allows the code to compile with c++11 and boost 1.53.0. Although I'm not sure why adding a non-const conversion operator would be expected to ensure the implicit conversion happens. I would expect the non-const conversion operator couldn't be called on a temporary object (maybe things are different when we have rvalue references?) In any case, the "convertible" in this reproducer is standing in for a class from Boost.Python, so I can't just add the extra non-const conversion operator to work around the problem. - bryan On Wed, May 15, 2013 at 1:54 PM, Antony Polukhin <antoshkka@gmail.com>wrote:
Hi Antony - Perhaps it is compiler dependent. Which version of MSVC did you reproduce the error with? Does that version have c++11 support enabled (in
2013/5/15 Bryan Catanzaro <bcatanzaro@acm.org>: particular,
rvalue references) As I said, with Boost 1.48.0, this code works with g++ 4.6 and 4.7. With 1.53.0, it works with g++ 4.6 and 4.7 only if c++11 support is turned off. If c++11 support is turned on, the code does not work. I've attached a shell script that compiles the attached code with the cross product of {(g++4.6, g++4.7), (boost1.48, boost1.53), (noc++11, yesc++11)}. As you can see from test.txt, the error happens only with boost 1.53 and c++11 support.
- bryan
Exactly the same things happen on GCC-4.5 and Clang-3.0.
But what is more interesting here: convertible c; const convertible& cc = c;
// Always compiles, using any flags, compiler and Boost version my_variant y = cc; my_variant y1 = static_cast<const convertible&>(c); my_variant y2 = static_cast<const convertible>(c);
// Always fail to compile, using any flags and Boost version // my_variant z = c; // my_variant y3 = static_cast<convertible&>(c);
Tested on clang, gcc4.5, gcc 4.6, gcc4.7 on Boost 1.48 and Boost 1.53 with and without C++11 flags.
If we modify `convertible`:
struct convertible { operator my_variant() { return my_variant(); }
operator my_variant() const { return my_variant(); } };
Then ALL the tests pass well, even the commented out ones. Even `my_variant y4 = static_cast<convertible&&>(c);` works well.
I'll test it tomorrow on Visual Studio 11 once more and investigate issue futher.
-- Best regards, Antony Polukhin

2013/5/16 Bryan Catanzaro <bcatanzaro@acm.org>:
Thanks for taking a look.
I checked, and on my system, you're right: adding a non-const conversion operator allows the code to compile with c++11 and boost 1.53.0. Although I'm not sure why adding a non-const conversion operator would be expected to ensure the implicit conversion happens. I would expect the non-const conversion operator couldn't be called on a temporary object (maybe things are different when we have rvalue references?)
Looks like things are different with rvalues. Visual Studio has rvalues enables by default and I know no way to disable them. BTW, MSVC10 and MSVC11 fail to compile all the tests even on Boost 1.48. Even those tests, that pass well on GCC and Clang (like `my_variant y1 = static_cast<const convertible&>(c)`) fail. Adding nonconst conversion operator did not help. All this stuff looks like a bug in some of compilers. I'll try to find correct behavior in C++ Standard and bug report to compiler developers. -- Best regards, Antony Polukhin
participants (2)
-
Antony Polukhin
-
Bryan Catanzaro