我正在尝试使用 GCC 8 中的 Concepts TS 复制标准 C++20 概念,以便我可以在标准库中提供它们之前使用它们。我主要复制粘贴最新草稿中的所有内容,然后遇到一个问题:
#include <type_traits>
#include <utility>
// [concept.same]
template <typename T, typename U>
concept bool Same = std::is_same_v<T, U>;
// [concept.assignable]
// TODO: Proper implementation requires std::common_reference that is not in
// libstdc++ yet and implementing it myself is too hard.
template <typename LHS, typename RHS>
concept bool Assignable = std::is_lvalue_reference_v<LHS> &&
requires(LHS lhs, RHS&& rhs)
{
{lhs = std::forward<RHS>(rhs)} -> Same<LHS>;
};
template <typename T>
requires Assignable<T&, T>
void Test(T a) {}
int main()
{
Test(42);
}
许多其他概念需要可分配类型,当尝试使用这个概念时,我得到:
Concepts.h:54:14: note: within 'template<class LHS, class RHS> concept const bool ftz::General::Assignable<LHS, RHS> [with LHS = int&; RHS = int]'
concept bool Assignable = std::is_lvalue_reference_v<LHS> &&
^~~~~~~~~~
Concepts.h:54:14: note: with 'int& lhs'
Concepts.h:54:14: note: with 'int&& rhs'
Concepts.h:54:14: note: unable to deduce placeholder type 'ftz::General::Same<int&>' from 'lhs =(forward<int>)(rhs)'
这里有什么问题?
这是最近对概念所做的更改,并在圣地亚哥(2018 年 11 月)采用,原因是:P1084 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1084r2.pdf。问题是以前是这样的:
{ E } -> Same<T>;
实际上意味着这个表达f(E)
对于以下形式的发明函数模板有效:
template <class U> requires Same<U, T> void f(U );
这显然永远不会适用于引用类型T
(如OP中所示)。
换句话说,旧规则是:{ E } -> Same<T>
meant Same<remove_cvref_t<decltype((E))>, T>
。新规则意味着Same<decltype((E)), T>
。看来海湾合作委员会的-fconcepts
clang 的概念分支也尚未实现这些新规则。
当前的解决方法是更改:
{ E } -> Same<LHS> // i.e. Same<T&>
to:
{ E } -> Same<std::remove_reference_t<LHS>>& // i.e. Same<T>&
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)