Re: Odd error I can't seem to recreate
On Nov 4, 1:03 pm, "Gennaro Prota" <gennaro.pr...@gmail.com> wrote:
On Fri, 04 Nov 2011 19:52:56 +0100, Noah Roberts <roberts.n...@gmail.com>
wrote:
In a significant code base I'm running into this problem:
This works:
test_service service;
std::string result = job->run_query(service);
This does not.:
std::string result = job->run_query(test_service());
the run_query function expects a const reference to test_service's
base class:
struct location_job
{
virtual ~location_job() {}
virtual std::string run_query(location_service const& service) c=
onst
= 0;
};
The error I get from g++4.1.2 is:
pipe_processor_test.cpp:142: error: no matching function for call to
=E2test_service::test_service(test_service)=E2
../inc/test_service.h:27: note: candidates are:
test_service::test_service(bool)
../inc/test_service.h:7: note:
test_service::test_service(test_service&)
The bool constructor is made by me, but the non-const copy constructor
is the compiler's. Line 7 is the opening brace for the class.
I can't make any sense of this. Does anyone have ANY idea what might
be going on so I can try to narrow it down and create a minimal
example to get better help? The attempts I've made so far work
fine.
Under what conditions in which the first could work might the second
not when the parameter is const ref? I can't think of any.
Thanks for any help that can be provided. I know it's a reach.
Try looking at the copy constructors of test_service's members:
- the direct and virtual base classes
- the non-static data members
At least one of them should have a copy constructor without
const-qualification on the first parameter, which is why the
compiler-generated copy constructor of test_service lacks it as
well.
Thanks. This does appear to be the main issue. There is an auto_ptr
in the test_service.
I recreated the problem:
cat wtf.cpp
#include <memory>
struct base
{
virtual ~base() {}
};
struct derived : base
{
std::auto_ptr<int> i;
derived() : i() {}
//private:
//derived(derived const&);
};
struct base;
struct base2
{
virtual ~base2() {}
virtual void fun(base const&) const = 0;
};
struct derived2 : base2
{
void fun(base const&) const {}
};
struct base3
{
virtual ~base3() {}
virtual std::auto_ptr<base2> get() const = 0;
};
struct derived3 : base3
{
std::auto_ptr<base2> get() const { return
std::auto_ptr<base2>(new derived2); }
};
int main()
{
derived3 d3;
std::auto_ptr<base2> b2 = d3.get();
b2->fun(derived());
}
Now I get all the errors I don't expect that are giving me crap in the
original code:
g++ wtf.cpp
wtf.cpp: In function =E2int main()=E2:
wtf.cpp:42: error: no matching function for call to
=E2derived::derived(derived)=E2
wtf.cpp:9: note: candidates are: derived::derived(derived&)
Victor said:
So, 'test_service' copy constructor takes a non-const reference. To
initialize the argument to your 'run_query', a temporary of type
'location_service' has to be created (or has to be able to be
created),
and I am guessing there is no conversion that the compiler can use.
..................
As I understood it, because it takes a non-const reference the
temporary created by the "test_service()" call should be directly
used, rather than a copy of it attempted. Why is it necessary to make
a temporary of 'location_service', or 'base' in the above code?