Summary
For some reason, my member function template that calls the lambda function cannot compile with error C2275 ... the illegal use of this type as an expression, but when a function is deduced to be a free function, it compiles correctly.
More details
First I have a base class that stores function instances in vector . Only derived classes can add function instances to this vector by calling add_external . All function instances can be called publicly by invoking invoke_externals . The derived class will add lambdas as function instances. These lambdas, in turn, invoke the invoke_internal base class function template with another "internal" lambdas. The invoke_internal template invoke_internal is the type of exception that will be explicitly caught when the "internal" lambda is invoke_internal in invoke_internal :
using namespace std; class base { public: void invoke_externals() { for (auto it = funcs_.begin(); it != funcs_.end(); ++it) { (*it)(); } } protected: void add_external(function<void(void)> func) { funcs_.push_back(func); } template <typename T> void invoke_internal(function<void(void)> func) { try { func(); } catch (const T&){} catch (...){} } vector<function<void(void)>> funcs_; };
Then I have two trivial free functions that throw logic_error and runtime_error . These functions should be used in the "internal" lambda, which is called in invoke_internal :
void throws_logic_error() { throw logic_error(""); } void throws_runtime_error() { throw runtime_error(""); }
Two lambdas with add_external are added to the constructor of the derived class. Each of these lambdas calls invoke_internal "internal" lmbdas. The first invoke_internal call will explicitly catch logic_error , which will throw throws_logic_error . The second invoke_internal call will explicitly catch the runtime_error that throws_runtime_error throws.
class derived : public base { public: derived() { add_external([this]() { invoke_internal<logic_error>([]() { throws_logic_error(); }); }); add_external([this]() { invoke_internal<runtime_error>([]() { throws_runtime_error(); }); }); } };
And to tie it all together, derived is created and invoke_externals is called to invoke the "external" lambdas added to the derived constructor. These "external" lambdas, in turn, will cause "internal" lambdas, and the thrown exceptions will be clearly caught:
int wmain(int, wchar_t*[]) { derived().invoke_externals(); return 0; }
Problem
However, the above does not compile:
error C2275: 'std::logic_error' : illegal use of this type as an expression error C2275: 'std::runtime_error' : illegal use of this type as an expression
... issued for invoke_internal calls in the derived constructor.
If I move invoke_internal from base and make it a free function, it compiles.
Question
Why am I getting error C2275 ... illegal use of this type as an expression when a function template is a base member?
Note. Moving the violation function from base not optimal, since in my real-life scenario, the function actually uses the state of its class in different ways.