C++11 - std::d eclval<T>() 方法名称

C++11 - std::declval<T>() name of method

本文关键字:方法 gt lt std eclval C++11      更新时间:2023-10-16

是否有一种方法,如何在std::declval<T>()之后传递方法名称作为模板参数?

到目前为止,我有这个:

template<typename T, typename ... Args>
struct MethodInfo
{
    using type = decltype(std::declval<T>().foo(std::declval<Args>() ...)) (T::*)(Args ...);
};

但我想" foo "是模板参数。

这不是你要求的,但我认为这可能符合你的需要:

#include <type_traits>
#include <tuple>
#include <iostream>
template<typename T, typename... Args>
struct MethodInfo {
    template<typename Ret>
    static auto get(Ret(T::*)(Args...)) -> Ret(T::*)(Args...);
};
struct Foo {
    int foo(int);
    int foo(int, int);
};
int main() {  
    static_assert(std::is_same<
                        int(Foo::*)(int), 
                        decltype(MethodInfo<Foo, int>::get(&Foo::foo))
                          >::value, "");
}

演示

因为,函数名是一个非类型模板参数,我认为这是目前为止唯一的解决方案。

在c++ 11中可以这样做,但它几乎违背了该类的目的:

template<typename T, typename U, U ptr, typename... Args>
struct TypeOverload;
template<typename T, typename U, typename... Args, U(T::* ptr)(Args...)>
struct TypeOverload<T, U(T::*)(Args...), ptr, Args...>
{
    using type = decltype((std::declval<T>().*ptr)(std::declval<Args>() ...)) (T::*)(Args ...);
};

的用法如下:

using bar_t = TypeOverload<Foo, decltype(&Foo::bar), &Foo::bar, int, int>::type;
static_assert(std::is_same<bar_t, void(Foo::*)(int,int)>::value, "");

演示

但是对于c++ 17中的auto模板参数,您可以这样做:

template<typename T, auto ptr, typename... Args>
struct TypeOverload
{
    using type = decltype((std::declval<T>().*ptr)(std::declval<Args>() ...)) (T::*)(Args ...);
};

,你可以这样使用它:

using bar_t = TypeOverload<Foo, &Foo::bar, int, int>::type;
static_assert(std::is_same<bar_t, void(Foo::*)(int,int)>::value, "");
演示