Domanda

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?

È stato utile?

Soluzione

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top