tags:

views:

81

answers:

3
template<class T>
struct IsFunc
{
    typedef char one;
    typedef struct 
    {
        char dummy_[2];
    } two;

    static one f(...);

    static two f(T (*)[1]);
    enum {value = (sizeof(f<T>(0)) == 1)};
};

And if I try to run it in main:

void functionA();
    int _tmain(int argc, _TCHAR* argv[])
    {
        int a = 0;
        cout << IsFunc<functionA>::value;//<=--------HERE

        return 0;
    }

I'm getting an error:
Error 1 error C2923: 'IsFunc' : 'functionA' is not a valid template type
What am I doing wrong?
Thanks

+3  A: 

functionA is a function, not a type, so it cannot be a valid template parameter to IsFunc which expects a type.

If you need a template to detect whether a type is a function type, there is already boost::is_function (which is part of TR1/C++0x).

KennyTM
IsFunc<void()> on the other hand, is fine :)
Armen Tsirunyan
@Armen : Thats because `void()` is a type id. The Standard says `A template-argument for a template-parameter which is a type shall be a type-id.`
Prasoon Saurav
There is nothing we can do
@There: Yes, boost::is_function
Armen Tsirunyan
@There: You need something like `decltype` (C++0x) or Boost.TypeOf (not very portable) to convert an identifier to a type.
KennyTM
@KennyTM but AFAIC Boost couldn't use themself to implement it so they had to use just plain "standard" C++ am I right? And if yes how is it done?
There is nothing we can do
@There: Boost.TypeOf depends on non-standard C++ feature, like g++'s `typeof`, otherwise it can only recognize a finite category of types. Fortunately function types can be detected by Boost.Typeof on compliant compilers.
KennyTM
+1  A: 

If you have template<class T> class X; you don't expect X<3> to work and deduce that T is int, do you? The same is here IsFunc<FunctionA> is invalid, but IsFunc<void()> is fine. HTH

Armen Tsirunyan
@Armen yes, you're absolutely right, although it would be nice if it would work that way, why not?
There is nothing we can do
@There: It would be nice if the program semantics were deduced by the compiler from the comments, don't you think? :)))))
Armen Tsirunyan
@Armen well I think what I've said isn't that silly and illogical, is it?
There is nothing we can do
@There: Sorry, I didn't want to offend you or somehow imply that your question is silly. But there are just soooo many things in C++ that it would be nice to have and that are far easier to implement that this particular one is definitely not in the priority list. anyway if you have a metafunction taking a type, you can easily convert it into a funtion - template<class Type> bool func(Type value) {return Metafunction<Type>::value;}
Armen Tsirunyan
@Armen ok +1.__________________
There is nothing we can do
@Armen is there an un/official site that I would be able to check "wish list" with features for C++?
There is nothing we can do
@There: Yeah, there is - http://www.open-std.org/JTC1/SC22/WG21/docs/standards, and it's official. Also post this kind of things in comp.lang.c++.moderated newsgroup, because many standards committee members read that newsgroup.
Armen Tsirunyan
+1  A: 

Others already stated the reason but would this help you?

#include <type_traits>
#include <typeinfo>
namespace
{
   template<typename T>
   bool test_if_function (T const &v)
   {
      return std::tr1::is_function<T>::value;
   }

   void functionA()
   {
   }
}

int main()
{
   printf ("%d\r\n", test_if_function (1));
   printf ("%d\r\n", test_if_function (functionA));

   return 0;
}
FuleSnabel
Requires TR1 obviously...
FuleSnabel