Typedef, keyword template and const

I have a problem using a template with the const keyword (for the type of the function argument), to illustrate it, I created tiny code:

template <typename ClassType, typename ReturnType, typename ... Args>
struct MethodCallerFactory
{
    typedef ReturnType (*Type)(ClassType*, Args...);

    template <ReturnType (ClassType::*Pointer)(Args...)>
    struct Method
    {
        static Type createMethodCaller()
        {
            ReturnType (*caller)(ClassType*, Args...) = [](ClassType* obj, Args ... args) -> ReturnType
            {
                 ReturnType (ClassType::*ptr)(Args...) = Pointer;
                                return (obj->*ptr)(args...);
            };
            return caller;
        }
   };
};


class Test
{
public :
        void set(const int& p)
        {
                n = p;
        }
        void set2(int p)
        {
                n = p;
        }
        void set3(const int p)
        {
                n = p;
        }
        void set4(int& p)
        {
                n = p;
        }
private :
        int n;
};

typedef int& INTREF;
typedef int INTVALUE;

int main()
{
        void (*ptr1)(Test*, const int&) = MethodCallerFactory<Test, void, const int&>::Method<&Test::set>::createMethodCaller();
        void (*ptr2)(Test*, const INTREF) = MethodCallerFactory<Test, void, const INTREF>::Method<&Test::set>::createMethodCaller();

        void (*ptr3)(Test*, int) = MethodCallerFactory<Test, void, int>::Method<&Test::set2>::createMethodCaller();
        void (*ptr4)(Test*, INTVALUE) = MethodCallerFactory<Test, void, INTVALUE>::Method<&Test::set2>::createMethodCaller();

        void (*ptr5)(Test*, int) = MethodCallerFactory<Test, void, const int>::Method<&Test::set3>::createMethodCaller();
        void (*ptr6)(Test*, const INTVALUE) = MethodCallerFactory<Test, void, const INTVALUE>::Method<&Test::set3>::createMethodCaller();

        void (*ptr7)(Test*, int&) = MethodCallerFactory<Test, void, int&>::Method<&Test::set4>::createMethodCaller();
        void (*ptr8)(Test*, INTREF) = MethodCallerFactory<Test, void, INTREF>::Method<&Test::set4>::createMethodCaller();
}

The only error I get is the declaration of the second pointer:

failed to convert template argument '& Test :: set to' void (Test :: *) (int &) void (ptr2) (Test, const INTREF) = MethodCallerFactory :: Method <& Test :: set> :: createMethodCaller ( );

It seems that when I use typedef with reference types, the compiler forgets the const keyword. I do not understand why there is a problem with this.

+4
source share
1 answer

, , const INTREF const int& ( int const&), int& const, const ( , a typedef, int& const). , int&, int const&.

:

#include <type_traits>

typedef int& INTREF;

int main()
{
    static_assert(std::is_same<const INTREF, int&>{}, "!");
}

, ( ) const - const -before ( ): , , 1 , , . INTREF const const INTREF, , , .


1 const , , . , " " int const* const ( const , ), const const int*; const int* const , const - const -, .

+6

All Articles