问题描述
我正在尝试使用GCC 8中的Concepts TS复制标准C ++ 20概念,以便在标准库中可用它们之前就可以使用它们。我主要复制了最新草案中的所有内容,然后遇到了一个问题:
I'm trying to replicate standard C++20 concepts using Concepts TS in GCC 8 so I can use them before they are available in standard library. I mostly copy pasted everything from the latest draft and I came across a problem:
#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);
}
很多其他概念需要可分配的类型,当尝试使用此概念时,我得到:
A lot of other concepts require assignable types and when trying to use this concept I get:
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)'
这里出了什么问题?
推荐答案
这是由于。问题是它曾经是:
This was a recent change made to Concepts that was adopted in the San Diego (November 2018) as a result of P1084. The problem is that it used to be that:
{ E } -> Same<T>;
实际上是指 f(E)
对于以下形式的发明函数模板有效:
Actually meant that the expression f(E)
is valid for an invented function template of the form:
template <class U> requires Same<U, T> void f(U );
显然,对于引用类型 T $ c,永远不会保留$ c>(与OP中一样)。
Which is obviously never going to hold for reference types T
(as in the OP).
换句话说,旧规则是: {E}->相同的
表示相同的,T>
。新规则是指 Same< decltype((E)),T>
。似乎gcc的 -fconcepts
和clang的concept分支都尚未实现这些新规则。
In other words, the old rule was that: { E } -> Same<T>
meant Same<remove_cvref_t<decltype((E))>, T>
. The new rule is that it means Same<decltype((E)), T>
. It appears that neither gcc's -fconcepts
nor clang's concepts branch implements these new rules yet.
当前的解决方法是更改:
A current workaround is to change:
{ E } -> Same<LHS> // i.e. Same<T&>
至:
{ E } -> Same<std::remove_reference_t<LHS>>& // i.e. Same<T>&
这篇关于无法推断概念中的占位符类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!