C ++概念lite和类型别名声明

时间:2016-10-30 19:54:54

标签: c++ typedef c++-concepts using-declaration

是否可以使用typedefusing在概念中声明类型别名,如概念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;
}

结果错误:

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
 } 
 ^

2 个答案:

答案 0 :(得分:2)

没有。根据TS的概念,要求是:

  

要求
  简单-要求
  型需求
  化合物-要求
  嵌套-要求

简单要求表达式后跟;类型要求类似{{ 1}}。另外两个听起来像顾名思义。

类型别名是声明,而不是表达式,因此不符合要求的要求。

答案 1 :(得分:2)

  

这对我来说是不必要的限制。您是否知道是否存在合理的解决方法而不是一遍又一遍地编写相同的复杂类型?

您可以将约束的实现推迟到另一个概念,将这些类型作为模板参数传递:

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>;

如果您正在考虑这样做,我建议您在做出决定之前尝试简单的示例。如何编写概念和约束决定了编译器如何报告错误,当然还有错误,这是使概念有用的重要部分。在更难理解错误的同时更容易编写我的概念并不是一种权衡,我会轻描淡写。

例如,这就是我将typename Cont::const_iterator;冗余地添加为显式约束的原因。这使编译器有机会报告此类型要求。我也非常谨慎地选择InsertableWith作为概念的名称:我可以很容易地使用detail::Insertable,但涉及Insertabledetail::Insertable的错误可能已经存在结果更令人困惑。

最后请注意,这一切都依赖于编译器的实现质量,所以我不认为任何方法暂时都是明确的。我鼓励玩这个Coliru demo