Boost.Variant broke in 1.54?

Dear all,
I get a compilation error with Boost.Variant (which compiles fine on
previous releases) with vstudio 2010 when a function returns a const
Boost.Variant, e.g.:
typedef boost::variant

On 8/4/2013 8:57 AM, gast128 wrote:
Dear all,
I get a compilation error with Boost.Variant (which compiles fine on previous releases) with vstudio 2010 when a function returns a const Boost.Variant, e.g.:
typedef boost::variant
Variant; const Variant GetVar() { return Variant(); }
void TestVariantDnc() { const Variant var = GetVar(); }
This gives error C2666 ('boost::variant
::convert_construct' : 3 overloads have similar conversions'). Shall a file a ticket or do I something wrong?
Returning a 'const X' is meaningless. Just return 'X' instead. The same goes for passing something as 'const X'. When you pass or return by value you get a copy of the object being passed so it means nothing to say that the object is 'const'.

Returning a 'const X' is meaningless. Just return 'X' instead. The same goes for passing something as 'const X'. When you pass or return by value you get a copy of the object being passed so it means nothing to say that the object is 'const'.
It's a recommendation of Scott Meyers, so that u cannot modify a temporary object. In the world of move constructors these days, that recommendation has become less valid. Having said that, your solution to this broken code is not to use it in the first place? Ofc I could have thought of that myself...

2013/8/4 Edward Diener
On 8/4/2013 8:57 AM, gast128 wrote: Returning a 'const X' is meaningless. Just return 'X' instead.
Just to clarify, Edward, I think you're wrong. Consider: struct X { void go() {} }; X source_a(); X const source_b(); int main() { source_a().go(); // ok source_b().go(); // error
The same goes for passing something as 'const X'.
I assume you mean a function *taking* something as 'const X'. Consider: void g( X x ); void g( X const x ); The two declarations of g() are equivalent (!), so you could say this 'const' is meaningless ;-). The 'const' here matters in the implementation of function g. void f( X x, X const y ) { x.go(); // ok y.go(); // error
When you pass or return by value you get a copy of the object being passed so it means nothing to say that the object is 'const'.
Considering what I've written above, I disagree that 'const' means nothing here. When function source_b() returns by const value, it *means* the returned temporary is const. When function f() takes by const value, it *means* the implementation of f() doesn't modify the copy it gets. For the caller of f(), this 'const' is meaningless indeed ;-) Regards, Kris

On 8/5/2013 7:47 AM, Krzysztof Czainski wrote:
2013/8/4 Edward Diener
mailto:eldiener@tropicsoft.com> On 8/4/2013 8:57 AM, gast128 wrote: Returning a 'const X' is meaningless. Just return 'X' instead.
Just to clarify, Edward, I think you're wrong. Consider:
struct X { void go() {} };
X source_a(); X const source_b();
int main() { source_a().go(); // ok source_b().go(); // error
The same goes for passing something as 'const X'.
I assume you mean a function *taking* something as 'const X'. Consider:
void g( X x ); void g( X const x );
The two declarations of g() are equivalent (!), so you could say this 'const' is meaningless ;-). The 'const' here matters in the implementation of function g.
void f( X x, X const y ) { x.go(); // ok y.go(); // error
When you pass or return by value you get a copy of the object being passed so it means nothing to say that the object is 'const'.
Considering what I've written above, I disagree that 'const' means nothing here. When function source_b() returns by const value, it *means* the returned temporary is const. When function f() takes by const value, it *means* the implementation of f() doesn't modify the copy it gets. For the caller of f(), this 'const' is meaningless indeed ;-)
I am aware of the syntax and its meaning. I specified "meaningless" not because the syntax is meaningless ( if it was the compiler would issue an error about the syntax itself ) but because the practical use of specifying 'const' in either situation is meaningless IMO. You are getting a copy of some X. Why would you practically specify that this copied value cannot be changed ? I do not see a practical programming reason for doing anything that way despite your correctly formed examples above. My reply was abrupt in that I should have specified as a suggestion that the 'const' just be dropped to solve the practical problem, not that the problem did not exist.

I am aware of the syntax and its meaning. I specified "meaningless" not because the syntax is meaningless ( if it was the compiler would issue an error about the syntax itself ) but because the practical use of specifying 'const' in either situation is meaningless IMO. You are getting a copy of some X. Why would you practically specify that this copied value cannot be changed ? I do not see a practical programming reason for doing anything that way despite your correctly formed examples above.
See item 21 'use const whenever possible 'of 'Effective C++', second edition. It is more to protect the programmer for accidental modifying temp objects which is probably a bug. With move ctor's there is actually a use case of modifying / stealing temp objects.

2013/8/4 gast128
Dear all,
I get a compilation error with Boost.Variant (which compiles fine on previous releases) with vstudio 2010 when a function returns a const Boost.Variant, e.g.:
typedef boost::variant
Variant; const Variant GetVar() { return Variant(); }
void TestVariantDnc() { const Variant var = GetVar(); }
This gives error C2666 ('boost::variant
::convert_construct' : 3 overloads have similar conversions').
I think this is an interesting example. For a copyable and movable type T: const T f(); int main() { T t = f(); //??? Should this: a) not compile? (like in the variant example above) b) use the copy constructor instead of moving? c) move anyway? Looks like this is caused by move-emulation for variant, isn't it? Regards, Kris

2013/8/4 gast128
Dear all,
I get a compilation error with Boost.Variant (which compiles fine on previous releases) with vstudio 2010 when a function returns a const Boost.Variant, e.g.:
typedef boost::variant
Variant; const Variant GetVar() { return Variant(); }
void TestVariantDnc() { const Variant var = GetVar(); }
This gives error C2666 ('boost::variant
::convert_construct' : 3 overloads have similar conversions'). Shall a file a ticket or do I something wrong?
Let me explain why this is not a good C++11 code any more.
Take a look at the following code:
const some_type GetVar()
{
return some_type();
}
Compiler instead of that will generate the following:
const some_type&& GetVar()
{
return some_type();
}
So now, when you'll try to do something like this
const some_type var = GetVar();
Compiler will convert that to the following:
const some_type var(GetVar());
Because usually there are no constructors for const rvalues, compiler will
use the copy constructor for some_type (`some_type(const some_type&)`).
So, adding a const disables all the move constructors and rvalue
optimizations.
However that does not mean that Boost.Variant can fail with that error. To
fix that error you can use the following trick:
* Find the line that has enable_if
participants (4)
-
Antony Polukhin
-
Edward Diener
-
gast128
-
Krzysztof Czainski