简体   繁体   English

是否可以(以及如何)为C ++模板功能参数添加类型协定检查?

[英]is it possible (and how) to add a type contract check for C++ template function parameter?

For example, I want to implement my own generic sort function, I want to require the type that would be passed in to be Indexable , and the element inside would be Comparable 例如,我想实现自己的通用排序功能,我希望将传入的类型设置为Indexable ,并且其中的元素应该是Comparable

template <typename Cont>
    **type_check: Cont is Indexable, Cont::Element is Comparable**
void my_sort(Cont& cont){
    // do sorting work
}

When I do my_sort(vector<int>{1,6,5,4}) would be okay 当我做my_sort(vector<int>{1,6,5,4})会没事的

But when do my_sort(linkedlist<int>{1,6,5,4}) would fail me at Compile/Runtime, because linkedlist is not Indexable . 但是my_sort(linkedlist<int>{1,6,5,4})会使我在编译/运行时失败,因为linkedlist不可Indexable

So is there a way to do such kind of type contract programming? 那么有没有办法进行这种类型的合同编程呢?

PS I am in C++ 11 environment, but any Solution in later version of C++ is also welcomed PS我在C ++ 11环境中,但是也欢迎使用更高版本的C ++中的任何解决方案

With SFINAE you can do something like: 使用SFINAE,您可以执行以下操作:

template <typename Cont>
auto my_sort(Cont& cont)
-> decltype(cont[42], // Indexable
            void(), // That void to avoid evil overload of operator comma
            std::declval<Cont::Element>() < std::declval<Cont::Element>(), // Comparable
            void()) // That final void for the return type of sort
{
    // do sorting work
}

std::enable_if is an alternative (to the decltype ) if you have the traits ready. 如果您已准备好特征,则std::enable_if是替代decltype

As mentioned in the comments, once the Concepts TS makes its way into the C++ standard, you'll be able to do this with something like: 如评论中所述,一旦Concepts TS进入C ++标准,您将可以通过以下方式实现此目的:

template <typename T>
concept Sortable = requires(T t) {
    { t[0] < t[0] } -> bool
};

template <Sortable Cont>
my_sort(Cont& cont) {
    // do sorting work
}

Live Demo 现场演示

An older version of the Concepts TS is implemented by GCC with the -fconcepts flag, but it won't be in the standard until C++20. GCC使用-fconcepts标志实现了较旧版本的Concepts TS,但直到C ++ 20才成为标准。 Until then, you can make do with SFINAE tricks: 在此之前,您可以使用SFINAE技巧:

template <typename Cont>
std::enable_if_t<std::is_convertible_v<decltype(std::declval<Cont>()[0] < std::declval<Cont>()[0]), bool>>
my_sort(Cont& cont) {
    // ...
}

This will fail to compile if, for a given Cont c , c[0] < c[0] is either not valid or not convertible to bool . 如果对于给定的Cont cc[0] < c[0]无效或不可转换为bool ,则将无法编译。
Live Demo 现场演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM