有没有办法,如何在std::declval<T>()
之后将方法名称作为模板参数传递?
到目前为止,我有这个:
template<typename T, typename ... Args>
struct MethodInfo
{
using type = decltype(std::declval<T>().foo(std::declval<Args>() ...)) (T::*)(Args ...);
};
但我希望“foo
”成为模板参数。
答案 0 :(得分:1)
在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, "");
答案 1 :(得分:1)
这不完全是你所问的,但我认为这可能有点符合你的需要:
#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, "");
}
因为,函数名是一个非类型模板参数,我认为这是唯一的解决方案,到目前为止。