C++ 概念相同且可赋值

Yon*_* Wu 2 c++ c++-concepts

我最近一直在尝试 C++ 概念。我正在尝试以下范围扩展文档中的定义:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4569.pdf

的定义和用法Same让我感到困惑。由于我不知道的原因,作者没有给出明确的定义。所以我正在使用:

template <class T, class U>
concept bool Same()
{
  return std::is_same<T, U>::value;
}
Run Code Online (Sandbox Code Playgroud)

问题是该文档给出了以下定义Assignable

template <class T, class U>
concept bool Assignable()
{
  return Common<T, U>() && requires(T&& a, U&& b) {
    { std::forward<T>(a) = std::forward<U>(b) } -> Same<T&>;
  };
}
Run Code Online (Sandbox Code Playgroud)

它不起作用(在 GCC 6.3 下):一个简单的Assignable<int&, int&&>()概念检查给了我false(我已经验证该Common部分没问题)。我必须更改Same<T&>才能T&使其看起来有效。同样的Same<Type>检查也用在其他一些地方。

我的问题是:

  • 我的定义Same正确吗?
  • 为什么Same<T&>用 代替T&?有什么区别?

谢谢你的帮助。

Yon*_* Wu 5

在周末解决这个问题之后,我想我自己已经找到了答案。

\n\n

Eric Niebler 和 Casey Carter 有一个更精确的定义,Same支持多个模板参数(不仅仅是两个),但我的定义应该基本上适合两个参数的情况。

\n\n

使用时-> Type,目的是使括号内的表达式可以隐式转换为Type. 使用时的-> Same<Type>目的是使括号内的表达式准确无误Type。所以他们是不同的。

\n\n

然而,有一个问题。约束检查相当复杂,甚至像Eric和Casey这样的专家也犯了错误,在N4569中给出了错误的定义。Eric 在 GitHub 上讨论了这个问题:

\n\n

https://github.com/ericniebler/stl2/issues/330

\n\n

当按照 N4569 中给出的方式使用时,这意味着表达式应该能够传递给想象的函数模板,例如

\n\n
template <typename U>\nf(U)\nrequires Same<T&, U>()\n
Run Code Online (Sandbox Code Playgroud)\n\n

这不起作用\xe2\x80\x94如果传入的表达式是 的左值T,则推导出来的U是。解决方案是使用在. 它将产生以下想象的函数模板:TT&Same<T&>&&Assignable

\n\n
template <typename U>\nf(U&&)\nrequires Same<T&, U>()\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在一切正常\xe2\x80\x94如果传入的表达式是 的左值TU则必须推导为T&

\n\n

玩弄概念对我来说是一个很好的实践,但我可能应该早点找到他们的代码。他们在以下 GitHub 存储库中有一套完整的概念:

\n\n

https://github.com/CaseyCarter/cmcstl2

\n\n

对 C++ 概念感兴趣的人应该研究一下。

\n