boost - Writing and checking your own concepts in c++ -


i writing header-only c++ library uses templates quite lot. want add concepts checking handle compile-time errors raised when incorrect types used in template parameters.

for example, need concept pointer-like objects point single object (like std::shared_ptr), pointer-like object point array (via operator[]) couldn't used pointer arithmetic (like std::unique_ptr), , pointers used pointer arithmetic , on.

since concepts still not in standard , not supported compilers, need implement myself. know boost concept library, reason not want add dependencies.

so question is, how implement checking of type requirements? how implemented in boost? techniques common in such cases?

i've done little bit of sort of thing myself since i've still been using c++11. essentially, way heavy use of sfinae , familiarity of these things: http://en.cppreference.com/w/cpp/types

the important of concept checking arguably enable_if: it's template provides given return type if first template parameter true , results in substitution failure if parameter false:

//this 1 gets called pointers template <typename t> typename enable_if<is_pointer<t>::value, bool>::type do_stuff(t) {}  //this 1 gets called non-pointers template <typename t> typename enable_if<not is_pointer<t>::value, bool>::type do_stuff(t) {} 

if don't care being able overload things , readable error messages, should use static_assert instead:

template <typename t> class pointer_thingy {     static_assert(is_pointer<t>::value, "t must pointer");     //... }; 

now, on more difficult part of this: defining own concept-like template things. if possible, best way write them in terms of existing standard ones link above. however, want check things aren't available there, like, say, availability of particular operation. in case sfinae friend:

template <typename t> class is_equality_comparable {     template <typename u> static auto check(const u& u) -> typename std::conditional<             std::is_convertible<decltype(u == u), bool>::value,             std::true_type, std::false_type>::type;     static std::false_type check(...); public:     static constexpr bool value = decltype(check(std::declval<t>()))::value; }; 

this checks if particular type has equality operator (operator==) defined , if returns can used bool. how warrants explanation, though: main thing class define check method never called , generate correct value computing check's return type. @ bottom, class that: determines return type of check when called imaginary value of type t (generated via declval in order avoid dependence on constructors). in order work correctly, 2 overloads of check provided: first templated , second uses ... notation in order accept arguments , have lower selection priority first overload. first overload uses suffix return type can refer parameter (which makes code a lot cleaner) , uses conditional choose between true_type , false_type based on whether operator== correctly returns can used bool. if operator== doesn't exist, first overload results in substitution failure , sfinae ensures quietly discarded list of possible overloads, meaning hypothetical call check falls second overload returns false_type.

of course, way of doing this; it's method works, i'm not sure if how boost or, matter, if how else it. if you're able use newer version of c++ real concepts support, should use instead: among other nice features, you'll able comprehensible error messages if wrong, not you'll out of methods mentioned above. final note, if decide this, rigorous testing crucial: it's easy wrong , hard figure out how fix when class used elsewhere in code.


Comments

Popular posts from this blog

yii2 - Yii 2 Running a Cron in the basic template -

asp.net - 'System.Web.HttpContext' does not contain a definition for 'GetOwinContext' Mystery -

mercurial graft feature, can it copy? -