6.5 Using Concepts to Simplify enable_if<> Expressions
6.5 使用Concepts简化enable_if<>表达式
Even when using alias templates, the enable_if syntax is pretty clumsy, because it uses a work-around: To get the desired effect, we add an additional template parameter and “abuse” that parameter to provide a specific requirement for the function template to be available at all. Code like this is hard to read and makes the rest of the function template hard to understand.
即使是使用别名模板,enable_if语法也是相当的笨拙。因为它使用一个变通方案:为了达到目的,我们用了一个额外的模板参数,并且“滥用”这个参数来提供一个有特定需求的可用函数模板。这样的代码不容易阅读,也使模板中剩作的代码很难理解。
In principle, we just need a language feature that allows us to formulate requirements or constraints for a function in a way that causes the function to be ignored if the requirements/constraints are not met.
原则上,我们只需要一种语言特性,它允许我们以某种方式为函数制定需求或约束。当需求/约束不满足时,函数就被忽略。
This is an application of the long-awaited language feature concepts, which allows us to formulate requirements/conditions for templates with its own simple syntax.
这就是人们期待己久的语言特性concepts的应用,可以通过其简单的语法对模板制定需求或约束。
Unfortunately, although long discussed, concepts still did not become part of the C++17 standard. Some compilers provide experimental support for such a feature, however, and concepts will likely become part of the next standard after C++17.
不幸的是,虽然己经讨论很久了。但是concept依然没有被纳入C++17标准。一些编译器目标对这一特性提供了试验性的支持,不过其很可能在C++17之后的标准中得到支持。
With concepts, as their use is proposed, we simply have to write the following:
根据其建议的用法,使用concept我们可以简单地编写如下:
template<typename STR> requires std::is_convertible_v<STR,std::string> Person(STR&& n) : name(std::forward<STR>(n)) { … }
We can even specify the requirement as a general concept
甚至可以将其中的requires条件定义成通用的concept
template<typename T> concept ConvertibleToString = std::is_convertible_v<T,std::string>;
and formulate this concept as a requirement:
并将这个concept作为requires的条件
template<typename STR> requires ConvertibleToString<STR> Person(STR&& n) : name(std::forward<STR>(n)) { … }
This also can be formulated as follows:
也可以写成下面这样:
template<ConvertibleToString STR> Person(STR&& n) : name(std::forward<STR>(n)) { … }
See Appendix E for a detailed discussion of concepts for C++.
关于C++中concept的细节,可参阅附录E。
6.6 Summary
6.6 小结
• In templates, you can “perfectly” forward parameters by declaring them as forwarding references (declared with a type formed with the name of a template parameter followed by &&) and using std::forward<>() in the forwarded call.
在模板中,可以通过将参数声明为“万能引用“(形如,模板参数T&&)和std::forward<>在模板调用中将参数”完美地“转发出去。
• When using perfect forwarding member function templates, they might match better than the predefined special member function to copy or move objects.
将完美转发用于成员函数模板时,当拷贝或移动对象时,他们可能比预定义的特殊成员函数更加匹配。
• With std::enable_if<>, you can disable a function template when a compile-time condition is false (the template is then ignored once that condition has been determined).
使用std::enable_if<>,可以在编译期条件为false时禁用函数模板(一旦确定条件了,该模板就会被忽略)
• By using std::enable_if<> you can avoid problems when constructor templates or assignment operator templates that can be called for single arguments are a better match than implicitly generated special member functions.
通过使用std::enable_if<>可以避免一些由于构造函数模板或赋值构造模板比隐式生成的特殊成员函数产生更好匹配而带来的问题。
• You can templify (and apply enable_if<>) to special member functions by deleting the predefined special member functions for const volatile.
可以通过删除对const volatile类型参数预定义的特殊成员函数,并结合使用std::enable_if<>,将特殊成员函数模板化。
• Concepts will allow us to use a more intuitive syntax for requirements on function templates.
concept允许我们使用更直观的语法对函数模板施加限制。