6

I'm trying to declare a template function pointer in C++.

template <class T>
class MyClass
{
public:
    typedef const unsigned char* (T::*MyTemplatedEvent)(unsigned long &myParameter);
};

but for some reason I keep getting this error:

'T': must be a class or namespace when followed by '::'

Can somebody tell what I'm doing wrong?
the compiler should know that T is a class. It says so above the MyClass declaration...

iammilind
  • 68,093
  • 33
  • 169
  • 336
Idov
  • 5,006
  • 17
  • 69
  • 106

5 Answers5

2

With T::*MyTemplatedEvent, you are expecting T to be a class type, since only class types can have member pointers. This means that if you pass a non-class type, say int or char*, you get the indicated error, as there are no members and conversely no member pointers for those types.

the compiler should know that T is a class. It says so above the MyClass declaration...

Wrong. class T is the same as typename T in a template parameter, and only tells the compiler that T is a placeholder for any type that is passed as a template argument later on. It does not restrict the type to be of class type.

Xeo
  • 129,499
  • 52
  • 291
  • 397
1

I'm guessing it's because I try to create "MyClass" of template which is a pointer or primitive which the compiler know can't have and function pointer associated with them...

Idov
  • 5,006
  • 17
  • 69
  • 106
  • Sorry, this is a non-answer. I am facing the same issue and looking for a real solution -- that's why I added a bounty. – Theo Sep 20 '12 at 22:32
  • 1
    @Theo: No, this is the answer, OP clarifies in a comment that he tries `MyClass` or `MyClass`. Those primitive types are by definition not class types. If you get this error but don't have similar code, you may want to post that as a stand-alone question. – Xeo Sep 21 '12 at 10:54
  • @Xeo: Thanks for the clarifications... I guess that this is not the issue I am facing then, since I am passing in a class as the template param. Will post a separate question. – Theo Sep 21 '12 at 17:46
  • @Xeo: Please add a separate response so I can give you the bounty -- your answer was the most helpful. – Theo Sep 26 '12 at 05:44
  • @Theo: I don't know what I should put in that answer, I only summed up the OP's comments and answer. :/ – Xeo Sep 26 '12 at 08:10
  • @Xeo: You can improve this question by writing a clearer version of the (very confusing) answer above -- even if it's just a summary taken from multiple comments found in all the dark corners of this page. This is what you largely did in your comment above. I'm asking you to do this because I can't cancel the bounty -- and so I'd rather award it to someone who was helpful in clarifying this question for me (that's you) rather than have the system award the bounty at random. – Theo Sep 26 '12 at 19:01
  • 1
    @Theo: Well, it's not like I'm gonna say no to rep if it's pushed onto me. ;) – Xeo Sep 26 '12 at 19:11
0

First note that in the definition of MyClass the two ways two declare the class as

template< class T > class MyClass

and

template< typename T > class MyClass

are equivalent, you are not giving the compiler more information by using one keyword over the other.

Beyond that, I'd say the compiler is right, MyClass< int > will not work because you can't write int::something in C++, whereas for example MyClass< std::string > will work perfectly well.

Seg Fault
  • 1,331
  • 8
  • 16
  • If whoever downvoted this could in some way elaborate on why, I'd be mighty interested. Thanks. – Seg Fault Sep 23 '12 at 18:53
  • (Not my downvote) Your logic is wrong. The replacement of `T` by `int` in the template is not a lexical replacement. You are allowed to use the `p->~T()` pseudo-destructor syntax in a template, and then instantiate it with `T==long long` even though you can't write `p->~long long()` outside that template. – MSalters Sep 24 '12 at 11:37
  • This destructor syntax is "faked" even for ints in the context that you say, but here we are speaking about a member function pointer at template instantiation time, and that's just too much. – Seg Fault Sep 24 '12 at 11:52
-1

Try to do the following:

typedef T type;
typedef const unsigned char* (type::*MyTemplatedEvent)(unsigned long &myParameter);
Forgottn
  • 563
  • 3
  • 11
-1

I dont think you can have a template function pointer in C++, you may check this link C++, function pointer to the template function pointer

"typedef const unsigned char* (T::*MyTemplatedEvent)(unsigned long &myParameter);" here T is template parameter not any namespace or class type, T is a datatype can be user defined or basic datatypes like int or char, but its not a Namespace or Class, so thats why you are getting the compilation error, which is correct.

Community
  • 1
  • 1
D Untouchable
  • 332
  • 4
  • 9
  • Yes you can have a template function pointer, the link you posted deals about a slightly different issue – Sdra Sep 26 '12 at 14:15
  • Sdra, can you please help me with a working code snippet of a template function pointer? I have not sure how to write one. – D Untouchable Sep 28 '12 at 04:07
  • @D Untouchable: yep ;) just post your code somewhere I can have a look to and let me know! – Sdra Oct 01 '12 at 10:16
  • @Sdra I meant can you please post a working code of template function pointer? function pointer declaration e.g.-> `void (*abc)(int)=NULL` probable template function pointer `template void (*abc) (T)=NULL;` – D Untouchable Oct 01 '12 at 12:20
  • @D Untouchable: BTW, this topic is about member functions of generic (template) classes. What you are asking instead is functions with generic (template) arguments. Here is an example of what you are asking... unfortunately I don't know if it will be correctly formatted: #include template void test( void (*handler)( T arg ), T argument ) { (*handler)( argument ); } template void handlerImpl( T arg ) { std::cout << "handlerImpl " << arg << std::endl; } int main() { test( handlerImpl, 10 ); test( handlerImpl, "Hello" ); return 0; } – Sdra Oct 01 '12 at 14:35