为什么C++20不支持"void f(Concept const auto&)"?
Why does C++20 not support "void f(Concept const auto&)"?
#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&)"?
概念名称必须出现在 auto
之前。或者:
void f(const Concept auto&)
或:
void f(Concept auto const&)
都有效。
动机是 (P1141):
To keep things simple, an auto
(or decltype(auto)
) being constrained is always immediately preceded by the constraint.
你的语法有误。
type-constraints,比如这里的概念HasSize
,直接属于placeholder-type-specifier之前,即在 auto
或 decltype(auto)
:
之前
void f6(const HasSize auto& arg) {}
参见 C++20 草案的 [dcl.spec.auto]。
cv-qualifiers,例如const
,与placeholder-type-specifiers是分开的,参见 [decl.type]/1。
正如@super 在问题评论中提到的,函数参数中不允许 decltype(auto)
。所以这似乎是一个接受它的 Clang 错误,请参阅 [dcl.spec.auto]/2 它只允许 auto 案例用于 placeholder-type-specifier 在函数参数中。
#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&)"?
概念名称必须出现在 auto
之前。或者:
void f(const Concept auto&)
或:
void f(Concept auto const&)
都有效。
动机是 (P1141):
To keep things simple, an
auto
(ordecltype(auto)
) being constrained is always immediately preceded by the constraint.
你的语法有误。
type-constraints,比如这里的概念HasSize
,直接属于placeholder-type-specifier之前,即在 auto
或 decltype(auto)
:
void f6(const HasSize auto& arg) {}
参见 C++20 草案的 [dcl.spec.auto]。
cv-qualifiers,例如const
,与placeholder-type-specifiers是分开的,参见 [decl.type]/1。
正如@super 在问题评论中提到的,函数参数中不允许 decltype(auto)
。所以这似乎是一个接受它的 Clang 错误,请参阅 [dcl.spec.auto]/2 它只允许 auto 案例用于 placeholder-type-specifier 在函数参数中。