简体   繁体   中英

Remove __attribute__((...)) from a function pointer or reference

#include <utility>
#include <iostream>

int main()
{
    using std_type = std::remove_reference<void (__attribute__((stdcall)) &)(int) noexcept>::type;
    using cdecl_type = std::remove_reference<void (__attribute__((cdecl)) &)(int) noexcept>::type;
    using type = std::remove_reference<void (&)(int) noexcept>::type;
    
    std::cout<<typeid(std_type).name()<<"\n";
    std::cout<<typeid(cdecl_type).name()<<"\n";
    std::cout<<typeid(type).name()<<"\n";
}

Output:

U7stdcallDoFviE
U5cdeclDoFviE
U5cdeclDoFviE

If I compare the types with std::is_same<std_type, cdecl_type>::value it returns false .

I need to remove the attribute so that the following code works, without having to have specializations for __stdcall :

template<typename T>
struct remove_class {};

template<typename C, typename R, typename... A>
struct remove_class<R(C::*)(A...)>
{
    using type = R(A...);
};

template <typename C, typename R, typename... A>
struct remove_class<R(C::*)(A...) const>
{
    using type = R(A...);
};

template<typename C, typename R, typename... A>
struct remove_class<R(C::*)(A...) volatile>
{
    using type = R(A...);
};

template<typename C, typename R, typename... A>
struct remove_class<R(C::*)(A...) noexcept>
{
    using type = R(A...);
};

template<typename C, typename R, typename... A>
struct remove_class<R(C::*)(A...) const volatile>
{
    using type = R(A...);
};

template<typename C, typename R, typename... A>
struct remove_class<R(C::*)(A...) const noexcept>
{
    using type = R(A...);
};

template<typename C, typename R, typename... A>
struct remove_class<R(C::*)(A...) volatile noexcept>
{
    using type = R(A...);
};

template<typename C, typename R, typename... A>
struct remove_class<R(C::*)(A...) const volatile noexcept>
{
    using type = R(A...);
};

template<typename T>
struct function_signature
{
    using type = typename remove_class<decltype(&std::remove_reference<T>::type::operator())>::type;
};

template<typename R, typename... A>
struct function_signature<R(A...)>
{
    using type = R(A...);
};

and:

template<typename T>
struct function_arguments_type
{
    using type = typename function_arguments_type<typename function_signature<T>::type>::type;
};

template<typename R, typename... A>
struct function_arguments_type<R(A...)>
{
    using type = typename std::tuple<A...>;
};

So that I can determine what is the return type of a function, and what is the type of its arguments.

Is there a way to remove the __attribute__((....)) from a function's signature or at least make my templates work without having to specialize every single one of them for __stdcall ?

You can still create a traits remove_stdcall , something like:

template <typename Func>
struct remove_stdcall
{
    using type = Func;
};

template <typename Ret, typename ... Args>
struct remove_stdcall<Ret __attribute__((stdcall)) (Args...) noexcept>
{
    using type = Ret(Args...) noexcept;
};

template <typename Ret, typename ... Args>
struct remove_stdcall<Ret __attribute__((stdcall))(Args...)>
{
    using type = Ret(Args...);
};

Demo .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM