创建`std :: forward`别名 - 意外结果

时间:2014-09-18 09:58:38

标签: c++ templates auto c++14 perfect-forwarding

我创建了一个std::forward别名,其行为与std::forward完全相同。

template<class T> 
constexpr decltype(auto) fwd(T mValue) noexcept
{ 
    return std::forward<T>(mValue); 
}

然后我在代码库中用std::forward<...>替换了fwd<...>的所有匹配项。

使用g++ 4.9编译了所有项目 - 所有测试都通过,一切正常。

然后我尝试使用clang++ 3.5进行编译。有些测试似乎随机失败,原因是fwd<...>。用std::forward<...>替换它再次修复了失败的测试。

我尝试使用尾随返回类型语法编写fwd<...>,因为我认为decltype(auto)无法正常工作:

template<class T> 
constexpr auto fwd(T mValue) noexcept -> decltype(std::forward<T>(mValue)) 
{ 
    return std::forward<T>(mValue); 
}

结果相同:g++有效,clang++没有。

然后我在cppreference上查找了std::forward的签名,并实现了我的别名:

template<class T> 
constexpr T&& fwd(std::remove_reference_t<T>& t) { return std::forward<T>(t); }

template<class T> 
constexpr T&& fwd(std::remove_reference_t<T>&& t) { return std::forward<T>(t); }

这在g++clang++上都有效(所有测试都通过)。

为什么decltype(auto)版本无效?它不应该返回与std::forward完全相同的返回类型吗?

1 个答案:

答案 0 :(得分:2)

您忘记将mValue声明为移动参考

template <typename T>
constexpr decltype(auto) fwd(std::remove_reference_t<T> &&mValue)
{
    return std::forward<T>(mValue);
}
template <typename T>
constexpr decltype(auto) fwd(std::remove_reference_t<T> &mValue)
{
    return std::forward<T>(mValue);
}