To simplify the testcase, suppose that I have the following wrapper class:
template <typename T>
struct Wrapper {
decltype(auto) operator()() const {
return m_t(); // <-- This is wrong
}
decltype(auto) operator()() {
return m_t();
}
T m_t;
};
template <typename T>
auto make_wrapper(T t) {
return Wrapper<T>{t};
}
And let’s say I am wrapping the following trivial functor returning references:
struct Foo {
int& operator()() {
return x;
}
const int& operator()() const {
return x;
}
int x;
};
In my main
function, I am trying to wrap the Foo
functor into a lambda closure. Since I want it to return non-const references, I am setting it mutable
and using decltype(auto)
:
int main() {
Foo foo;
auto fun = [foo]() mutable -> decltype(auto) { return foo(); };
auto wfun = make_wrapper(fun);
const auto& cwfun = wfun;
wfun(); // <- OK
cwfun(); // <- BAD!
}
For the second call, cwfun()
, the first const
version of Wrapper::operator()
is called, but there m_t
is then viewed as a const
lambda, and thus cannot be called. I suppose this is because m_t
was marked mutable
in the first place. So what would be a good way of making that work? Convert m_t
to a non-const
before calling it in operator() const
?
The error message given by clang looks like:
tc-refptr.cc:8:12: error: no matching function for call to object of type 'const (lambda at
tc-refptr.cc:40:14)'
return m_t();
^~~
tc-refptr.cc:44:27: note: in instantiation of member function 'Wrapper<(lambda at
tc-refptr.cc:40:14)>::operator()' requested here
DebugType<decltype(cwfun())> df;
^
tc-refptr.cc:40:14: note: candidate function not viable: 'this' argument has type 'const
(lambda at tc-refptr.cc:40:14)', but method is not marked const
auto fun = [foo]() mutable -> decltype(auto) { return foo(); };
Aucun commentaire:
Enregistrer un commentaire