Concept of Checking Changes in C ++?

I am migrating some code from one project to another in my company and I came across a generic "sets_intersect" function that won't compile:

template<typename _InputIter1, typename _InputIter2, typename _Compare>
bool sets_intersect(_InputIter1 __first1, _InputIter1 __last1,
                    _InputIter2 __first2, _InputIter2 __last2,
                    _Compare __comp)
{
    // Standard library concept requirements
    // These statements confuse automatic indentation tools.
    // concept requirements
    __glibcpp_function_requires(_InputIteratorConcept<_InputIter1>)
    __glibcpp_function_requires(_InputIteratorConcept<_InputIter2>)
    __glibcpp_function_requires(_SameTypeConcept<
          typename iterator_traits<_InputIter1>::value_type,
          typename iterator_traits<_InputIter2>::value_type>)
    __glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
          typename iterator_traits<_InputIter1>::value_type>)
    __glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
          typename iterator_traits<_InputIter1>::value_type,
          typename iterator_traits<_InputIter2>::value_type>)

    while (__first1 != __last1 && __first2 != __last2)
    if (__comp(*__first1, *__first2))
            ++__first1;
    else if (__comp(*__first2, *__first1))
            ++__first2;
    else {
            return true;
    }
    return false;
}

      

I'm new to this concept of "concepts" (sorry for the pun), so I pondered a bit in the C ++ standard library and some search engines and I see that these macros __glibcpp_function_requires

have been changed to __glibcxx_function_requires

. So my compiler bug has been fixed; however, since this is new to me, I am wondering what this code does for me, and am having trouble finding any documentation or decrypting the code in the library.

My guess is that the point of these macros is that when the compiler extends the templated function, they will run some compile-time type checking to make sure the container being used is compatible with that algorithm. In other words, I am assuming that the first call checks to see if it _InputIter1

matches _InputIteratorConcept

. Am I just confused or am I on the right track? Also, why were the names of these macros changed in the C ++ standard library?

+2


source to share


4 answers


You are correct, the first call checks that _InputIter1

the "input iterator" concept implements .

These macros are internal GLIBC implementation details (starting with underscore or double underscore), so GLIBC developers are allowed to modify them as they see fit. They should not be used by user code.



Since "concepts" are no longer part of the C ++ 0x project, in order to have a portable validation concept, you must use some third party library, such as the Boost Performance Testing Library .

+1


source


"Concepts" was a suggested feature for the next release C++

, but they were (relatively) recently voted out of the standard so won't reappear for a quote.

They were designed to check the requirements for template parameters early and, among other things, would allow for much more succinct error messages when a type that did not meet the required constraints was used to instantiate the template.



2nd Edit: (see comments from dribeas and Jerry Coffin). These g ++ macros are internal concept checking mechanisms and are not directly related to the proposed new language feature of the same name. Since they are internal to g ++, you can (and probably should) safely remove them without losing functionality in your function template.

+3


source


There are two conceptual concepts (pun intended). The standard, as defined, has a proposal for concepts as a standard language feature that would aid compilation and ... there was little literature around C ++ 0x concepts, discussions ...

Another concept of the concept is the one you just clicked. The STL, which is deployed with g ++ implementations, has certain implementation checks that are also meant to help you catch errors. They differ from previous concepts in that they are not language features and are not intended to be used by programmers, but rather are used within a library. Since the names are reserved (they start with double underscores), the compiler / library developer can add anything there as long as the library's behavior does not differ from what the standard defines.

Getting back to what you are doing: the code you are trying to hook into a newer compiler is a modified version std::set_intersect

as defined in the [lib.set.intersection] standard to only return if they intersect without having to parse all two range. I would either use the standard version, or check that the output iterator has not been modified, or if it is a performance issue, implement it without a proof of concept, depending on the non-standard hidden symbols of the compiler asks for service issues when the compiler is updated, but you already know.

+1


source


As Charles already pointed out, direct support for concepts as part of C ++ 0x has been removed from the language relatively recently, and will almost certainly not even be revisited until the next round of standardization. Hopefully by then there will be more agreement on what they really should / do.

However, a large number of libraries try to provide similar capabilities. The Boost Concept Check Library is probably the most obvious one, and I believe most of the others are based on it, at least in concept (if you're "sorry for the pun). As for why the guys at g ++ decided to go with" * cxx "to" * cpp ", I can't even guess - other than that they seem to think breaking compatibility as often as possible is a good thing (although they really are for internal use only, so changing the name shouldn't break too much, but their own code).

This is also quite similar to the basic idea that Andrei Alexandrescu presented in § 2.1 of Modern C ++ Design. If you need some idea of ​​how to write your own checks, you can read this (and also § 2.7, where he applies similar techniques to test for convertibility and inheritance). While the concepts being tested are different, they are well versed in basic techniques, so:

  1. You have a decent opportunity to read and understand the authentication patterns.
  2. If you've ever decided to write your own, you have a starting point.

Edit: It might be worth noting that the standard libraries for most modern C ++ compilers contain at least some kind of concept-checking templates. Obviously gnu does. So is Como. In fact, the only thing I can think of doesn't seem to include things like MS VC ++ (which uses the Dinkumware library). They mainly concentrated on some (rather expensive) runtime debugging. It's also somewhat useful, but in a completely different direction, and both are not mutually exclusive at all.

0


source







All Articles