Reputation: 38173
So, defining a predicate inside a function and use as std::list::remove_if
argument is not allowed?
Consider the following code, which fails to compile:
struct a { };
int main()
{
struct pred { bool operator()( const a& ) { return false; } };
std::list< a > l; // fill l
l.remove_if( pred() );
return 0;
}
error: no matching function for call to
‘std::list<a, std::allocator<a> >::remove_if(main()::pred)’
Now, if I replace l.remove_if( pred() );
with
pred()( *l.begin() );
// or
pred p;
p( *l.begin() );
which remove_if
does internally, it compiles and works as expected.
And even more: if I move struct pred
to be defined outside main, both tests work as expected.
This doesn't make any sense to me.
I thought that it could be something with dependent names and ADL and things like this, but... the argument of remove_if
is an instance, not a type. It's true, that this is a template function and the argument's type is still resolved, but..
Can somebody explain what and why happens?
Upvotes: 2
Views: 1329
Reputation: 96281
The answer to your very first question is that yes, prior to C++11 some types (such as local types) are NOT allowed as template parameters. See 14.3.1/2:
A local type, a type with no linkage, an unnamed type or a type compounded from any of these types shall not be used as a template argument for a template type parameter.
Since remove_if
is a template, you cannot use the local predicate as its parameter.
Upvotes: 4