函数参数的类型是否可以推导?

时间:2017-07-06 14:32:18

标签: c++ decltype return-type-deduction

我有一个使用返回码的类:

class MyClass
{
    // ...

public:
    // ValueType get_value() const;               // usual code
    ErrorCode get_value(ValueType& value) const;  // uses error code

   // ...
};

因此,get_value()的第二种形式实际上将值作为函数参数提供,而不是作为返回值。

是否可以使用get_value()来推断decltype的函数参数的类型?

int main()
{
    // ...

    MyClass my_class;
    // auto val = my_class.get_value();  // okay: value has correct type

    declytype( /* something here */ ) value;
    const auto error = my_class.get_value( value );

    // ...
}

2 个答案:

答案 0 :(得分:6)

如果要推断参数的类型,可以使用模板来执行此操作:

namespace detail
{
    template<typename>
    struct Helper;

    template<typename R, typename C, typename T>
    struct Helper <R(C::*)(T)>
    {
        using type = T;
    };
}

然后使用它:

detail::Helper<decltype(&MyClass::get_value)>::type value;
// ...
const auto error = my_class.get_value(value);

有关详细信息,请参阅related question

答案 1 :(得分:1)

更紧凑的解决方案,无需完全定义新类型。

您可以使用函数声明(无需定义)和decltype来执行此操作 它遵循一个最小的工作示例:

#include<type_traits>

template<typename R, typename C, typename T>
constexpr T f(R(C::*)(T));

struct S {
    void f(int) {}
};

int main() {
    static_assert(std::is_same<int, decltype(f(&S::f))>::value, "!");
}

您还可以使用元组轻松地将其扩展为多个参数:

template<typename R, typename C, typename... T>
constexpr std::tuple<T...> f(R(C::*)(T...));

在C ++ 17中,您还可以使用auto模板参数获得更加用户友好的类型处理程序:

template<auto M>
using Type = decltype(f(M));

并将其用作:

static_assert(std::is_same_v<int, Type<&S::f>>);