#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&)”?
您的语法错误。
type-constraints(例如此处的概念HasSize
)直接在placeholder-type-specifier之前,即auto
或decltype(auto)
:
void f6(const HasSize auto& arg) {}
请参阅C ++ 20草案的[dcl.spec.auto]。
cv-qualifier,例如const
,与placeholder-type-specifier分开,请参阅[decl.type]/1。
概念名称必须出现在auto
之前。要么:
void f(const Concept auto&)
或:
void f(Concept auto const&)
都有效。
动机是(P1141):
为了简单起见,要约束的
auto
(或decltype(auto)
)总是紧随其后。