Sli*_*red 9 c++ typedef using-declaration c++-concepts
是否可以使用typedef或using在概念中声明类型别名,如概念TS所提议的那样?如果我尝试类似下面的MWE,代码不会编译(使用gcc 6.2.1和-fconcepts开关)
#include <type_traits>
template<typename T>
concept bool TestConcept ()
{
return requires(T t)
{
using V = T;
std::is_integral<V>::value;
};
}
int main()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
结果错误:
main.cpp: In function ‘concept bool TestConcept()’:
main.cpp:8:9: error: expected primary-expression before ‘using’
using V = T;
^~~~~
main.cpp:8:9: error: expected ‘}’ before ‘using’
main.cpp:8:9: error: expected ‘;’ before ‘using’
main.cpp:4:14: error: definition of concept ‘concept bool TestConcept()’ has multiple statements
concept bool TestConcept ()
^~~~~~~~~~~
main.cpp: At global scope:
main.cpp:11:1: error: expected declaration before ‘}’ token
}
^
Run Code Online (Sandbox Code Playgroud)
不可以。根据 TS 的概念,要求是:
需求:
简单需求
类型需求
复合需求
嵌套需求
其中简单要求是一个表达式,后跟 a ;,类型要求类似于typename T::inner. 另外两个听起来就像名字所暗示的那样。
类型别名是声明,而不是表达式,因此不满足要求的要求。
这对我来说是不必要的限制。您是否知道是否存在合理的解决方法,而不是一遍又一遍地编写相同的复杂类型?
您可以将约束的实现推迟到另一个概念,将这些类型作为模板参数传递:
template<typename Cont, typename It, typename Value>
concept bool InsertableWith = requires(Cont cont, It it, Value value) {
// use It and Value as much as necessary
cont.insert(it, std::move(value));
};
template<typename Cont>
concept bool Insertable = requires {
// optional
typename Cont::const_iterator;
typename Cont::value_type;
} && InsertableWith<Cont, typename Cont::const_iterator, typename Cont::value_type>;
Run Code Online (Sandbox Code Playgroud)
如果您正在考虑这样做,我建议您在做出决定之前先尝试一些简单的示例。如何编写概念和约束决定了编译器如何报告错误,当然,良好的错误是使概念变得有用的一个重要部分。让我更容易地写出我的概念,同时让我更难理解错误,这并不是一个我会轻易做出的权衡。
例如,这就是为什么我多余地添加了typename Cont::const_iterator;显式约束。这使编译器有机会报告此类型要求。InsertableWith我在选择概念名称时也很谨慎:我本可以轻松地选择detail::Insertable,但涉及 和 的错误Insertable可能detail::Insertable会导致更加混乱。
最后请注意,这一切都依赖于编译器的实现质量,因此我不期望任何方法暂时是确定的。我鼓励玩这个Coliru 演示。