At Fri, 8 Jan 2016 01:29:54 +0000 Nathan Ridge wrote:
Hi there,
I'm experiencing a compiler error in code that tries to assign a Boost.Phoenix function object returned by invoking a phoenix::function with a std::string as one of the bound parameters.
I've reduced my error to the following minimal code:
#include <string> #include
#include struct S { void operator()(std::string, int) const; };
boost::phoenix::function<S> lazy;
auto func1 = lazy(std::string(), boost::phoenix::placeholders::_1); auto func2 = func1;
void foo() { func2 = func1; }
My compiler version is clang 3.7; the error does not occur with gcc 5.1.
The error also goes away if I change the type of the first argument from std::string to a different type (like int).
The compiler error is shown below. Any ideas as to what is going on? Am I doing something wrong, or did I run into a bug in Phoenix?
Thanks, Nate
Every Phoenix actor has three `operator=` functions. One is a normal copy assignment, and the other two are for generating lazy assignment functions (one takes a mutable actor, and the other an immutable one). Gcc is selecting the copy assignment in this instance, and Clang is selecting the lazy assignment function. I believe Gcc is correct in this circumstance, because the copy-assignment function is not templated and therefore should take precedence according to the overload resolution rules. So I _think_ this is a bug in Clang. This came up in boost log over a year ago; Joel and I thought it was a bug in Clang at the time. We should've provided them with a minimal example to see their answer (maybe Joel did?) - I will reduce this further and provide it to them unless you feel the need to. This is unlikely to be an issue with phoenix before C++11 because it requires a named instance of a phoenix actor, and few wanted to write the monstrous type manually. Example: namespace phx = boost::phoenix; int foo; auto lazy_assign = (phx::ref(foo) = phx::placeholders::_1); `lazy_assign` is a phoenix actor, whose `operator()` will take the first argument by const reference and assign it to `foo`. But it is also a phoenix actor like `phoenix::ref`, so: lazy_assign = (phx::placeholders::_2); tries to create new phoenix actor (lazy function), whose semantics are really confusing (and thus an error is likely appropriate). Lee