c++ - 通过 lambda 部分特化类模板

标签 c++ templates lambda c++14 variadic-templates

我有存储函数或成员函数信息(如返回类型、数字或参数等)的模板类型。

template<class R, class... FuncParams>
struct SFuncInfo
{
    using Signature = R(FuncParams...);
    using Ret = R;

    static constexpr size_t numParams = sizeof...(FuncParams);
};

// member
template<class T, class Ret, class... Params>
struct SFuncInfo<Ret(T::*)(Params...)> : SFuncInfo<Ret, Params...> 
{
    static constexpr bool isMemberFunction = true;
};

// function
template<class R, class... FuncParams>
struct SFuncInfo<R(FuncParams...)> : SFuncInfo<R, FuncParams...> 
{
    static constexpr bool isMemberFunction = false;
};

它是这样使用的:

int func(const char* str) { return 1; }

struct MyType
{
    bool memFunc(int val, float fl) { return true; }
};

int main() 
{
    static_assert(!SFuncInfo<decltype(func)>::isMemberFunction, "");
    static_assert(std::is_same<SFuncInfo<decltype(func)>::Ret, int>::value, "");

    static_assert(SFuncInfo<decltype(&MyType::memFunc)>::isMemberFunction, "");
    static_assert(std::is_same<SFuncInfo<decltype(&MyType::memFunc)>::Ret, bool>::value, "");
}

此代码编译。但我也想用 lambda 处理案例。像这样:

auto lambda = [](int, bool) -> float { return 3.14f; };

static_assert(SFuncInfo<decltype(lambda)>::isMemberFunction, "");
static_assert(std::is_same<SFuncInfo<decltype(lambda)>::Ret, float>::value, "");

我尝试了不同的选择。下面列出了其中的一小部分。

template<class T>
struct SFuncInfo<T, decltype(T())>
{
    static constexpr bool isMemberFunction = true;
};

template<class T>
struct SFuncInfo<T, decltype(&std::decay<decltype(std::declval<T>())>::type::operator())>
{
    static constexpr bool isMemberFunction = true;
};

它不解析任何这些特化。

顺便说一下,下面的代码也可以编译:

auto lambda = [](int, bool) -> float { return 3.14f; };

using LambdaType = std::decay<decltype(std::declval<decltype(lambda)>())>::type;
using CallOperator = decltype(&LambdaType::operator());
static_assert(std::is_same<SFuncInfo<CallOperator>::Ret, float>::value, "");
static_assert(SFuncInfo<CallOperator>::isMemberFunction, "");

这里是 LIVE DEMO是不是有人想玩。

有没有人对此有好的解决方案?

最佳答案

添加这个单一的部分特化对我有利:

template<class Lambda>
struct SFuncInfo<Lambda> : SFuncInfo<decltype(&Lambda::operator())> { };

关于c++ - 通过 lambda 部分特化类模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55538020/

相关文章:

c++ - 是什么限制了我在内存方面对堆栈的使用?

c++ - Qt5/C++ 在 mousePressEvent 期间释放鼠标

c++ - 为什么我可以在不包含 STL 的情况下使用 nullptr?

c++ - 自定义强制转换不适用于派生类的引用

c++ - decltype 与具有默认参数的函数模板会产生困惑的结果(一个有趣的问题或 gcc 的错误)

c# - 为什么 MSDN 站点上的这个 lambda 示例不起作用?

c++ - 在 C++ 中使用循环遍历数组,程序显示 "exit status -1"?

c++ - 表达式模板 - 修饰名称长度超出

C++ 11 lambda作为成员变量?

python - 带有 lambda 函数的 sorted()