c++ 从模板参数获取函数元数

wribegjk  于 2023-07-01  发布在  其他
关注(0)|答案(2)|浏览(160)

我怎样才能得到一个任意函数类型的arity作为一个模板参数?
这个函数可以是一个普通函数,一个lambda或一个仿函数。示例:

template<typename TFunc>
std::size_t getArity() 
{
    // ...? 
}

template<typename TFunc>
void printArity(TFunc mFunc)
{
    std::cout << "arity: " << getArity<TFunc>() << std::endl;
}

void testFunc(int) { }

int main()
{
    printArity([](){}); // prints 0
    printArity([&](int x, float y){}); // prints 2
    printArity(testFunc); // prints 1
}

我可以访问所有C++14特性。
我必须为每个函数类型(以及所有相应的限定符)创建专门化吗?还是有更简单的方法?

wxclj1h5

wxclj1h51#

假设我们正在讨论的所有operator()和函数都不是模板或重载:

template <typename T>
struct get_arity : get_arity<decltype(&T::operator())> {};
template <typename R, typename... Args>
struct get_arity<R(*)(Args...)> : std::integral_constant<unsigned, sizeof...(Args)> {};
// Possibly add specialization for variadic functions
// Member functions:
template <typename R, typename C, typename... Args>
struct get_arity<R(C::*)(Args...)> :
    std::integral_constant<unsigned, sizeof...(Args)> {};
template <typename R, typename C, typename... Args>
struct get_arity<R(C::*)(Args...) const> :
    std::integral_constant<unsigned, sizeof...(Args)> {};

// Add all combinations of variadic/non-variadic, cv-qualifiers and ref-qualifiers

Demo

vaqhlq81

vaqhlq812#

几年后,但看到我的完整(免费)解决方案here(生产级,完全文档化)。在您的情况下,您需要帮助模板“ArgCount_v”(在上面的链接中有完整的文档)。将其应用于您自己的代码(显示预期的结果-请参阅here):

#include <iostream>

// See https://github.com/HexadigmSystems/FunctionTraits
#include "TypeTraits.h" 

template<typename TFunc>
void printArity(TFunc mFunc)
{
    ////////////////////////////////////////////////
    // Everything in "TypeTraits.h" above declared
    // in this namespace
    ////////////////////////////////////////////////
    using namespace StdExt;

    /////////////////////////////////////////////////////  
    // Note: "tcout" (declared in "TypeTraits.h" above)
    // always resolves to "std::cout" on non-Microsoft
    // platforms and usually "std::wcout" on Microsoft
    // platforms (when compiling for UTF-16 in that
    // environment which is usually the case). You can
    // directly call "std::cout" or "std::wcout" instead
    // if you prefer, assuming you know which platform
    // you're always running on.
    /////////////////////////////////////////////////////  
    tcout << "arity: " << ArgCount_v<TFunc> << std::endl;
}

void testFunc(int) { }

int main()
{
    printArity([](){}); // prints 0
    printArity([&](int x, float y){}); // prints 2
    printArity(testFunc); // prints 1

    return 0;
}

相关问题