成员函数参数的类型

Type of member functions arguments

本文关键字:类型 参数 函数 成员      更新时间:2023-10-16

使用C 11我试图从函数名称中获取函数参数的类型,授予函数签名是明确的。最终,我试图检查一个参数恰好是我想要的类型我调用函数。

到目前为止,由于此解决方案,我可以使用非会员功能来完成:将功能参数的参数解开到C 模板类

我已经对其进行了一些编辑以获取以下类:

template<typename T>
struct FunctionSignatureParser; // unimplemented primary template
template<typename Result, typename...Args>
struct FunctionSignatureParser<Result(Args...)>
{
    using return_type = Result;
    using args_tuple = std::tuple<Args...>;
    template <size_t i> struct arg
    {
        typedef typename std::tuple_element<i, args_tuple>::type type;
    };
};

例如,我可以在编译时检查功能的类型:

short square(char x) { // 8-bit integer as input, 16-bit integer as output
    return short(x)*short(x);
}
int main() {
        char answer = 42;
        static_assert(std::is_same<char, FunctionSignatureParser<decltype(square)>::arg<0>::type>::value, "Function 'square' does not use an argument of type 'char'");
        static_assert(std::is_same<short, FunctionSignatureParser<decltype(square)>::return_type>::value, "Function 'square' does not return a value of type 'short'");
        short sqrAnswer = square(answer);
        std::cout << "The square of " << +answer << " is " << +sqrAnswer << std::endl;
        return 0;
}

>>与GCC的在线代码

但是,当我想检查成员功能的类型时,一些编译器对此不满意:

struct Temperature
{
    double degrees;
    Temperature add(double value);
};
int main() {
    Temperature t{16};
    double increment{8};
    static_assert(std::is_same<double, FunctionSignatureParser<decltype(t.add)>::arg<0>::type>::value, "Method 'Temperature::add' does not use an argument of type 'double'");
    std::cout << t.degrees << u8" u00b0C + " << increment << " == " << t.add(increment).degrees << u8" u00b0C" << std::endl;
    return 0;
}

这是GCC 6.3所说的:

错误:非静态成员函数的使用无效'温度温度:: add(double)'

>>与GCC的在线代码

这是Clang 4.0所说的:

错误:必须调用对非静态成员函数的引用

>>与clang的在线代码

我尝试了这些选项,无济于事:

decltype(Temperature::add)
decltype(std::declval<Temperature>().add)

decltype内的非静态成员功能有什么问题?由于未评估decltype中的表达式,因此static预选赛不重要,对吧?

为了记录,MSVC12在这种情况下成功。不过,我无法分辨Microsoft编译器是对还是错。(请不要让这个线程成为编译器战争)

另外,如果您有一个不涉及初始方法的参数检查解决方案,我也为此开放。

您需要另一个模板专业化成员功能,类似的东西:

template<typename ClassType, typename Result, typename...Args>
struct FunctionSignatureParser<Result(ClassType::*)(Args...)>
{
    using return_type = Result;
    using args_tuple = std::tuple<Args...>;
    template <size_t i> struct arg
    {
        typedef typename std::tuple_element<i, args_tuple>::type type;
    };
};

可以这样使用:

    static_assert(std::is_same<double, FunctionSignatureParser<decltype(&Temperature::add)>::arg<0>::type>::value, "Method 'Temperature::add' does not use an argument of type 'double'");

这与GCC 7.2一起使用,尚未测试其他编译器