This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

C++ template to find out if a class has a certain function/method

I tried the example from the following article:

http://www.gockelhut.com/c++/articles/has_member

It seems not to work with the Ti C++ compiler. Is there any explanation why not?

Best regards

Thomas

  • First, the header type_traits is not available in C++98, which is what the compiler supports.  This header file is available in C++11, which the TI compiler does not yet support.

    Second, how exactly do you know that it does not work with the TI compiler?   Do you get an error message?  What is the exact text of the message?  Does it behave incorrectly?  Do you have a complete, compilable test case that demonstrates the problem?

  • Actually its not a problem of any header.

    The compiler result bahaves wrong. As descriped in the article i get for both:

    struct No { };
    struct Yes {void foo(int x); };

    bool value1=has_foo<No>::value;// -> false;
    bool value2=has_foo<Yes>::value;// ->false; instead of ->true

    Everything else should be described in the article.

    Best regards

    Thomas

  • Well, I can't reproduce this problem with the stock TI compiler, because it does not provide that header file.  From where are you getting the header file type_traits?  There are two example implementations in the article, a "simple" and a "real" implementation.  Do you get the incorrect result with both the simple and real implementations?

  • I do not need any header file!

    Just the code of the first simple template class has_foo.

     

  • I cannot reproduce this; the "simple" example works fine for me with ARM compiler version 4.9.1

    What command-line options are you using?

    Here is the code I used:

    template <typename T>
    class has_foo
    {
    private:
        template <typename U, U>
        class check
        { };
        
        template <typename C>
        static char f(check<void (C::*)(int), &C::foo>*);
        
        template <typename C>
        static long f(...);
        
    public:
        static const bool value = (sizeof(f<T>(0)) == sizeof(char));
    };
    
    #include <stdio.h>
    
    struct no { };
    struct yes { void foo(int x); };
    struct wrong_proto { void foo(double x); };
    
    int main()
    {
        printf("has_foo<no>::value == %d\n", has_foo<no>::value);
        printf("has_foo<yes>::value == %d\n", has_foo<yes>::value);
        printf("has_foo<wrong_proto>::value == %d\n", has_foo<wrong_proto>::value);
        return 0;
    }
    
  • Archaeologist said:
    I cannot reproduce this

    I take that back; I was not actually using 4.9.1.  Okay, I can reproduce this using ARM compiler version 4.9.1.  I'll look at it a bit more.

  • I've submitted SDSCM00045882 to track this issue.  The characterization of the bug is beyond me; I'll have to let someone else handle it.

  • Actually I work with Compiler version:

    tms470_4.9.5

     

  • Actually I commented the follwing lines:

    template <typename T>
    class has_foo
    {
    private:
        template <typename U, U>
        class check
        { };
       
        template <typename C>
        static char f(check<void (C::*)(int), &C::foo>*);
       
        //template <typename C>
        //static long f(...);
       
    public:
        static const bool value = (sizeof(f<T>(0)) == sizeof(char));
    };

    #include <stdio.h>
    struct no { };
    struct yes { void foo(int x); };
    struct wrong_proto { void foo(double x); };
    int main()
    {
        //printf("has_foo<no>::value == %d\n", has_foo<no>::value);
        printf("has_foo<yes>::value == %d\n", has_foo<yes>::value);
        //printf("has_foo<wrong_proto>::value == %d\n", has_foo<wrong_proto>::value);
        return 0;

    Then there is the following compiler error:

    "D:/projekte/ByLIF/src/app/bylif/main.cpp", line ...: error #306: no instance of function template "has_foo<T>::f [with T=yes]" matches the argument list
    argument types are: (int)
    >> Compilation failure detected during instantiation of class "has_foo<T> [with T=yes]" at line ...

    So there is a problem with the zero pointer in sizeof(f<T>(0))
    The compiler expects a "static ... f(int);" method. But there is just a "static char f(check<void (C::*)(int), &C::foo>*);"

     

     

     

  • After a long time of trying I've found a workaround for this problem:

    template <typename T>
    class has_foo
    {
    private:
        template <typename U>
        struct check
        {
         typedef U FNC; template<FNC> class Fnc{};
        };

        template <typename C>
        static char f(typename check<void (C::*)(int)>::template Fnc<&C::foo>*);

        template <typename C>
        static long f(...);

    public:
        static const bool value = (sizeof(f<T>(0)) == sizeof(char));
    };

    #include <stdio.h>
    struct no { };
    struct yes {void foo(int x); };
    struct wrong_proto { void foo(double x); };

    int main(void)
    {
        printf("has_foo<no>::value == %d\n", has_foo<no>::value);
        printf("has_foo<yes>::value == %d\n", has_foo<yes>::value);
        printf("has_foo<wrong_proto>::value == %d\n", has_foo<wrong_proto>::value);
        return 0;
    }