boost::make_optional 与类型规范

问题描述

我对与模板规范一起使用时的 boost::make_optional() 行为感到困惑。

特别是,我仍然不清楚为什么会这样:

int pizza = 5;
boost::optional<int> pizza_opt = boost::make_optional<int>(pizza)

抛出编译错误无法将‘int&&’类型的右值引用绑定到‘int’类型的左值;而这个:

int foo(int bar)
{ return bar; }

boost::optional<int> pizza_opt = boost::make_optional<int>(foo(pizza))

工作正常。

我已经从 this 知道使用 boost::make_optional 指定类型没有多大意义,但我正在阅读一些使用这种结构的代码

谢谢!

解决方法

boost::make_optional 的模板参数没有在 optional 中准确定义类型。

这个模板参数负责完美转发,这里是简单的最小示例重现问题:

#include <iostream>

template<typename T>
void bar(T&& x)
{
    std::cout << __PRETTY_FUNCTION__ << " " 
        << std::forward<T>(x) << '\n';
}

int foo(int x)
{
    return x + 1;
}

int main()
{
    int pizza = 5;
    bar(pizza);
    bar<int>(foo(pizza));
    // bar<int>(pizza); // same error

    return 0;
}

Live demo

所以当推导完成后,左值的 T 是 int&,右值的 T 是 int

当你传递变量时,你传递的是左值。

当您指定类型时,您将强制参数为与 int && 不匹配的 int&