为什么C++20不支持“void f(Concept const auto &)”?

5
#include <string>

template<typename T>
concept HasSize = requires(T obj)
{
    obj.size();    
};

void f1(HasSize auto arg) {} // ok
void f2(HasSize auto&& arg) {} // ok
void f3(HasSize decltype(auto) arg) {} // ok
void f4(HasSize auto& arg) {}  // ok
void f5(HasSize auto* arg) {}  // ok

void f6(HasSize const auto& arg) {} // error

int main()
{
    std::string str{};

    f1(std::string{});
    f2(std::string{});
    f3(std::string{});
    f4(str);
    f5(&str);
    f6(str);
}

使用 clang++ -std=c++20 -stdlib=libc++ z.cpp 编译,出现以下错误信息:

z.cpp:15:6: error: variable has incomplete type 'void'
void f6(HasSize const auto& arg) {} // error
     ^
z.cpp:15:9: error: too few template arguments for concept 'HasSize'
void f6(HasSize const auto& arg) {} // error
        ^
z.cpp:4:9: note: template is declared here
concept HasSize = requires(T obj)
        ^
z.cpp:15:33: error: expected ';' after top level declarator
void f6(HasSize const auto& arg) {} // error
                                ^
                                ;
3 errors generated.

为什么C++20不支持“void f(Concept const auto&)"?

2
不知道是否回答了你的问题,但是 auto const& 似乎可以工作。此外,gcc 不喜欢 HasSize decltype(auto) arg。在这种情况下,这甚至意味着什么? - super
2个回答

8
你的语法有误。 类型约束,比如这里的概念HasSize,应该直接放在占位类型说明符autodecltype(auto)之前。
void f6(const HasSize auto& arg) {}

请参阅C++20草案的[dcl.spec.auto]

[decl.type]/1所述,constcv限定符占位类型说明符分开。


正如@super在问题评论中提到的,decltype(auto)在函数参数中是不允许的。因此,这似乎是Clang支持它的一个错误,请参见[dcl.spec.auto]/2,该规范仅允许在函数参数中使用占位符类型说明符的auto情况。


8
概念名称必须出现在 auto 的正前方。两种方式如下:
void f(const Concept auto&)

或者:

void f(Concept auto const&)

两者都是有效的。

这一做法的动机是(P1141):

为了保持简单,对一个被约束的 auto(或 decltype(auto))总是紧随其后直接放置约束。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接