By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,655 Members | 959 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,655 IT Pros & Developers. It's quick & easy.

Local class instances invalid template argument

P: n/a
Hello,

I thought one major advantage of using functors as e.g. sorting
predicates over functions would be that I can do something like this:

void foo()
{
class Predicate
{
public:
bool operator() (...) {...}
};

std::list<whatever> lst;
// ...
std::transform( lst.begin(), lst.end(), lst.begin(), Predicate() );
}

However, I am getting a compile time error "type foo()::Predicate
composed from a local class is not a valid template-argument".

Why?

--
Regards,
Matthias
Jul 23 '05 #1
Share this Question
Share on Google+
10 Replies


P: n/a
Matthias wrote:
Hello,

I thought one major advantage of using functors as e.g. sorting
predicates over functions would be that I can do something like this:

void foo()
{
class Predicate
{
public:
bool operator() (...) {...}
};

std::list<whatever> lst;
// ...
std::transform( lst.begin(), lst.end(), lst.begin(), Predicate() );
}

However, I am getting a compile time error "type foo()::Predicate
composed from a local class is not a valid template-argument".

Why?


Whoops, this should read:

lst.sort( ..., Predicate() );

--
Regards,
Matthias
Jul 23 '05 #2

P: n/a

Matthias wrote:
class Predicate
{
public:
bool operator() (...) {...}
};


Make sure it takes the correct arguments.

-shez-

Jul 23 '05 #3

P: n/a
Shezan Baig wrote:
Matthias wrote:
class Predicate
{
public:
bool operator() (...) {...}
};

Make sure it takes the correct arguments.

-shez-


When taking the exact same class outside the function scope, everything
works just fine. I doubt it had something to do with the arguments.

--
Regards,
Matthias
Jul 23 '05 #4

P: n/a
Hi,

Matthias wrote:
Hello,

I thought one major advantage of using functors as e.g. sorting
predicates over functions would be that I can do something like this:

void foo()
{
class Predicate
{
public:
bool operator() (...) {...}
};

std::list<whatever> lst;
// ...
std::transform( lst.begin(), lst.end(), lst.begin(), Predicate() ); }

However, I am getting a compile time error "type foo()::Predicate
composed from a local class is not a valid template-argument".

Why?

Because the standard say so:

14.3.1 paragraph 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
templateargument for a template typeparameter.
[Example:
template <class T> class X { /* ... */ };
void f()
{
struct S { /* ... */ };
X<S> x3; // error: local type used as templateargument
X<S*> x4; // error: pointer to local type used as templateargument
}
-end example] [Note: a template type argument may be an incomplete
type (3.9). ]"

But, see the following link:
http://groups-beta.google.com/group/...m&hl=en&rnum=2
..
..
Best regards,
Bogdan Sintoma

Jul 23 '05 #5

P: n/a
Bogdan Sintoma wrote:
Hi,

Matthias wrote:
Hello,

I thought one major advantage of using functors as e.g. sorting
predicates over functions would be that I can do something like this:

void foo()
{
class Predicate
{
public:
bool operator() (...) {...}
};

std::list<whatever> lst;
// ...
std::transform( lst.begin(), lst.end(), lst.begin(), Predicate()


);
}

However, I am getting a compile time error "type foo()::Predicate
composed from a local class is not a valid template-argument".

Why?


Because the standard say so:

14.3.1 paragraph 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
templateargument for a template typeparameter.
[Example:
template <class T> class X { /* ... */ };
void f()
{
struct S { /* ... */ };
X<S> x3; // error: local type used as templateargument
X<S*> x4; // error: pointer to local type used as templateargument
}
-end example] [Note: a template type argument may be an incomplete
type (3.9). ]"

But, see the following link:
http://groups-beta.google.com/group/...m&hl=en&rnum=2
.
.
Best regards,
Bogdan Sintoma


Ah, that's clever, in fact simply making the local type also a non-local
type by subtyping it from a non-local type.
I wonder if you need the additional overhead this delegation produces at
all. Couldn't you just inherit from an empty non-local class? That would
make your type non-local as well, and you wouldn't have to do that
delegation stuff... Just an idea.

--
Regards,
Matthias
Jul 23 '05 #6

P: n/a
Matthias wrote:
Bogdan Sintoma wrote:
Hi,

Matthias wrote:
Hello,

I thought one major advantage of using functors as e.g. sorting
predicates over functions would be that I can do something like this:

void foo()
{
class Predicate
{
public:
bool operator() (...) {...}
};

std::list<whatever> lst;
// ...
std::transform( lst.begin(), lst.end(), lst.begin(), Predicate()

);
}

However, I am getting a compile time error "type foo()::Predicate
composed from a local class is not a valid template-argument".

Why?


Because the standard say so:

14.3.1 paragraph 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
templateargument for a template typeparameter.
[Example:
template <class T> class X { /* ... */ };
void f()
{
struct S { /* ... */ };
X<S> x3; // error: local type used as templateargument
X<S*> x4; // error: pointer to local type used as templateargument
}
-end example] [Note: a template type argument may be an incomplete
type (3.9). ]"

But, see the following link:
http://groups-beta.google.com/group/...m&hl=en&rnum=2

.
.
Best regards,
Bogdan Sintoma


Ah, that's clever, in fact simply making the local type also a non-local
type by subtyping it from a non-local type.
I wonder if you need the additional overhead this delegation produces at
all. Couldn't you just inherit from an empty non-local class? That would
make your type non-local as well, and you wouldn't have to do that
delegation stuff... Just an idea.


Ah yes of course, nevermind. Got a misunderstanding there, but hey, it
works :)

--
Regards,
Matthias
Jul 23 '05 #7

P: n/a
Bogdan Sintoma wrote:
But, see the following link:
http://groups-beta.google.com/group/...m&hl=en&rnum=2
.
.
Best regards,
Bogdan Sintoma


Hm, I am getting an error:
localclass.cpp: In constructor `FunctorWrapper<T>::FunctorWrapper(const
FunctorBase<T>&) [with T = int]':
localclass.cpp:39: instantiated from here
localclass.cpp:17: error: invalid initialization of reference of type '
FunctorBase<int>&' from expression of type 'const FunctorBase<int>'

Here is the code (I have taken out the abstraction of the return type):

template<typename T>
class FunctorBase
{
public:
virtual bool operator() ( const T& ) const = 0;
};

template<typename T>
class FunctorWrapper
{
FunctorBase<T>& _functor;
public:
FunctorWrapper( const FunctorBase<T>& rf )
: _functor(rf) {}

bool operator() ( const T& t ) const {
return _functor(t);
}
};
int main()
{
std::list<int> l;
class Functor: public FunctorBase<int>
{
public:
bool operator() (const int& n) const {
return true;
}
};

Functor f;
FunctorWrapper<int> w(f);

std::transform( l.begin(), l.end(), l.begin(), w );
}
--
Regards,
Matthias
Jul 23 '05 #8

P: n/a
Matthias wrote:
Here is the code (I have taken out the abstraction of the return type):
template<typename T>
class FunctorBase You should derive the FunctorBase from unary_function<T, bool>.
{
public:
virtual bool operator() ( const T& ) const = 0;
};

template<typename T>
class FunctorWrapper
{
FunctorBase<T>& _functor;
public:
FunctorWrapper( const FunctorBase<T>& rf )

Here is the problem: ^^^
Either you store your _functor as a const reference either you modify
the constructor to receive a non-const reference. And avoid the leading
underscore ;).

Jul 23 '05 #9

P: n/a
Bogdan Sintoma wrote:
Matthias wrote:
Here is the code (I have taken out the abstraction of the return
type):
template<typename T>
class FunctorBase


You should derive the FunctorBase from unary_function<T, bool>.


Why?
{
public:
virtual bool operator() ( const T& ) const = 0;
};

template<typename T>
class FunctorWrapper
{
FunctorBase<T>& _functor;
public:
FunctorWrapper( const FunctorBase<T>& rf )
Here is the problem: ^^^
Either you store your _functor as a const reference either you modify
the constructor to receive a non-const reference.


Oh, of course :) Thanks.

And avoid the leading underscore ;).


Why? It's my way of notating a member variable. This way you directly
see which variable is a member and which is not. I used to use m_ but _
is shorter :)

--
Regards,
Matthias
Jul 23 '05 #10

P: n/a
Matthias wrote:
You should derive the FunctorBase from unary_function<T, bool>.

Why?

Again, because the c++ standard say so ;)
Chapter 20.3 paragraph 5.
"To enable adaptors and other components to manipulate function objects
that take one or two arguments it is required that the function objects
correspondingly provide typedefs argument_type and result_type for
function objects that take one argument and first_argument_type,
second_argument_type, and result_type for function objects that take
two arguments."

You can just provide those typedefs, but that's exactly what
unary_function is for.

And avoid the leading underscore ;).

Why? It's my way of notating a member variable. This way you directly
see which variable is a member and which is not.
I used to use m_ but _ is shorter :)


According to the standard:
"17.4.3.1.2 Global names
1 Certain sets of names and function signatures are always reserved to
the implementation:
- Each name that contains a double underscore (_ _) or begins with an
underscore followed by an uppercase letter (2.11) is reserved to the
implementation for any use.
- Each name that begins with an underscore is reserved to the
implementation for use as a name in the
global namespace.165)"

So, not every name that start with an underscore is restricted, but it
is more easy to avoid leading underscore than to keep in mind all of
above :).

....
Bogdan

Jul 23 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.