【问题标题】:How to deduce the return type of a function which takes a reference as parameter如何推断以引用为参数的函数的返回类型
【发布时间】:2014-02-26 11:44:21
【问题描述】:

我正在尝试推断函数的返回类型并将其用作成员函数的返回类型。为此,我使用了 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();
}

【问题讨论】:

  • 为了让func1 工作,将m_data 的声明移到它前面。 Example

标签: c++ c++11 pass-by-reference decltype return-type-deduction


【解决方案1】:

我想你在找std::declval&lt;data_type&amp;&gt;()

【讨论】:

    【解决方案2】:

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

    对于第二个,标准库提供了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);
        }
    };    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-17
      • 2020-06-06
      • 1970-01-01
      • 1970-01-01
      • 2020-03-23
      • 1970-01-01
      • 2021-07-18
      • 1970-01-01
      相关资源
      最近更新 更多