如何推断以引用为参数的函数的返回类型

How to deduce the return type of a function which takes a reference as parameter

本文关键字:函数 返回类型 参数 何推断 引用      更新时间:2023-10-16

我正在尝试推断函数的返回类型并将其用作成员函数的返回类型。为此,我使用了一个 decltype 表达式。但是如果给定的函数将引用作为参数,我的所有尝试都无法编译:

  • 我不能在 decltype 表达式中使用我的类的任何成员变量,因为编译器抱怨没有这样的成员(见下文func1
  • 我不能对函数参数使用临时值,因为该函数接受引用,并且您不能将非常量左值引用绑定到临时引用(请参阅下面的func2

我还尝试了各种强制转换运算符来使引用临时使用,但似乎没有什么是有效的表达式。

下面是一个代码示例:

template<typename data_type, typename functor_type>
class MyClass
{
public:
    auto func1() -> decltype(functor_type::process(this->m_data)) // <--
    {
        return functor_type::process(m_data);
    }
    auto func2() -> decltype(functor_type::process(data_type{})) // <--
    {
        return functor_type::process(m_data);
    }
private:
    data_type m_data;
};
struct Functor
{
    static int process(int& a) { return a; }
};
int main()
{
    MyClass<int, Functor> m;
    int b = m.func1();
    int c = m.func2();
}
我想

你正在寻找std::declval<data_type&>()

第一个失败是因为类在函数声明中不完整,因为它在成员函数体中不完整,因此只能使用已声明的成员。

对于第二种,标准库提供 declval ,一个声明为返回其模板参数类型的函数模板。当您需要特定类型的表达式时,可以在未计算的上下文中使用它。

所以以下版本应该有效:

#include <utility> // for declval
template<typename data_type, typename functor_type>
class MyClass
{
private:
    // Declare this before `func1`
    data_type m_data;
public:
    // Use the already declared member variable
    auto func1() -> decltype(functor_type::process(m_data))
    {
        return functor_type::process(m_data);
    }
    // Or use `declval` to get an expression with the required reference type
    auto func2() -> decltype(functor_type::process(std::declval<data_type&>()))
    {
        return functor_type::process(m_data);
    }
};