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

xml*_*lmx 5 c++ standards templates c++-concepts c++20

#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);
}
Run Code Online (Sandbox Code Playgroud)

编译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.
Run Code Online (Sandbox Code Playgroud)

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

wal*_*nut 8

你的语法错误。

type-constraints,比如HasSize这里的概念,直接在placeholder-type-specifier之前,即在autoor之前decltype(auto)

void f6(const HasSize auto& arg) {}
Run Code Online (Sandbox Code Playgroud)

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

CV-限定符S,例如const,是从单独的占位符型说明符S,见[decl.type] / 1


正如@super 在问题评论中提到的那样,decltype(auto)函数参数中不允许。所以这似乎是一个接受它的 Clang 错误,请参阅[dcl.spec.auto]/2,它只允许函数参数中占位符类型说明符自动大小写。


met*_*fox 7

概念名称必须出现在 之前auto。任何一个:

void f(const Concept auto&)
Run Code Online (Sandbox Code Playgroud)

或者:

void f(Concept auto const&)
Run Code Online (Sandbox Code Playgroud)

都是有效的。

动机是(P1141):

为了简单起见,被约束的auto(or decltype(auto)) 总是紧跟在约束之前。