C++ 如何推导以引用为参数的函数的返回类型

C++ 如何推导以引用为参数的函数的返回类型,c++,c++11,pass-by-reference,decltype,return-type-deduction,C++,C++11,Pass By Reference,Decltype,Return Type Deduction,我试图推导函数的返回类型,并将其用作成员函数的返回类型。为此,我使用decltype表达式。但是,如果给定函数以引用作为参数,则我的所有尝试都无法编译: 我不能在decltype表达式中使用我的类的任何成员变量,因为编译器抱怨没有这样的成员(请参见下面的func1) 我不能对函数参数使用临时变量,因为函数采用引用,并且不能将非常量左值引用绑定到临时变量(请参见下面的func2) 我还尝试了各种铸造操作员,使参考采取临时,但似乎没有什么是一个有效的表达 下面是一个代码示例: template&

我试图推导函数的返回类型,并将其用作成员函数的返回类型。为此,我使用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();
}
模板
类MyClass
{
公众:

auto func1()->decltype(functor_type::process(this->m_data))//decltype(functor_type::process(data_type{}))//我想你在找
std::declval()
我想你在找
std::declval()
我想你在找
std::declval()
我想你在找

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

对于第二种情况,标准库提供了
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);
    }
};    
#包括//declval
模板
类MyClass
{
私人:
//在'func1'之前声明此项`
数据类型m_数据;
公众:
//使用已声明的成员变量
auto func1()->decltype(functor\u type::process(m\u数据))
{
返回函子类型::进程(m_数据);
}
//或者使用'declval'获取具有所需引用类型的表达式
auto func2()->decltype(functor_type::process(std::declval()))
{
返回函子类型::进程(m_数据);
}
};    

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

对于第二种情况,标准库提供了
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);
    }
};    
#包括//declval
模板
类MyClass
{
私人:
//在'func1'之前声明此项`
数据类型m_数据;
公众:
//使用已声明的成员变量
auto func1()->decltype(functor\u type::process(m\u数据))
{
返回函子类型::进程(m_数据);
}
//或者使用'declval'获取具有所需引用类型的表达式
auto func2()->decltype(functor_type::process(std::declval()))
{
返回函子类型::进程(m_数据);
}
};    

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

对于第二种情况,标准库提供了
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);
    }
};    
#包括//declval
模板
类MyClass
{
私人:
//在'func1'之前声明此项`
数据类型m_数据;
公众:
//使用已声明的成员变量
auto func1()->decltype(functor\u type::process(m\u数据))
{
返回函子类型::进程(m_数据);
}
//或者使用'declval'获取具有所需引用类型的表达式
auto func2()->decltype(functor_type::process(std::declval()))
{
返回函子类型::进程(m_数据);
}
};    

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

对于第二种情况,标准库提供了
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);
    }
};    
#包括//declval
模板
类MyClass
{
私人:
//在'func1'之前声明此项`
数据类型m_数据;
公众:
//使用已声明的成员变量
auto func1()->decltype(functor\u type::process(m\u数据))
{
返回函子类型::进程(m_数据);
}
//或者使用'declval'获取具有所需引用类型的表达式
auto func2()->decltype(functor_type::process(std::declval()))
{
返回函子类型::进程(m_数据);
}
};    

对于
func1
一个要工作,将
m_数据的声明移到它前面。对于
func1
一个要工作,将
m_数据的声明移到它前面。对于
func1
一个要工作,将
m_数据的声明移到它前面。对于
func1
一个要工作,将
m_数据的声明移到它前面ata
在其前面。