Detecting Valid Expressions for a Type at Compile-Time
Hi,
Is there a way, using SFINAE tricks and potentially the techniques
used in the Boost Concept Check Library, to detect at compile-time if
a type T supports a certain expression? In my case, I'm interested if
T supports operator ==. So I'm basically looking for a compile-time
predicate so that this compiles:
struct my_struct { int i; };
struct my_struct2 { int i; };
bool operator == (my_struct2 const&, my_struct2 const&) const;
BOOST_STATIC_ASSERT((supports_comparison_operator<int>::value));
BOOST_STATIC_ASSERT((!supports_comparison_operator
On Sun, July 22, 2007 06:08, Martin Ecker wrote:
Hi,
Is there a way, using SFINAE tricks and potentially the techniques used in the Boost Concept Check Library, to detect at compile-time if a type T supports a certain expression? In my case, I'm interested if T supports operator ==. So I'm basically looking for a compile-time predicate so that this compiles:
struct my_struct { int i; }; struct my_struct2 { int i; }; bool operator == (my_struct2 const&, my_struct2 const&) const;
BOOST_STATIC_ASSERT((supports_comparison_operator<int>::value)); BOOST_STATIC_ASSERT((!supports_comparison_operator
::value)); BOOST_STATIC_ASSERT((supports_comparison_operator ::value)); Thanks, Martin
Hi Martin, if you simply would like to ensure that you compile a correct version, I would suggest the following solution: A template function which compares a type instance with itself (makes no sense during the runtime since is always true, if there is a comparison operator, otherwise a compiler error is issued) template<class Type_> inline void concept_comparison_exists(Type_ const& t) { static_cast<bool>(t==t); } static_cast<bool>(t==t) is used to notify that compiler that this is an intended code and no warning should be produced. Now some tests: class SomeClassX //empty class to ensure that out concept works {}; int main(int argc, char* argv[]) { int i = 8; concept_comparison_exists(i); concept_comparison_exists(SomeClassX()); return 0; } I think any compiler will optimize away the concept check, since it expands to some unrefereced boolean value. Calling the object's ctor is just done for test purposes. Compiler might not optimize a ctor call if it does something meaningful (but if you pass to the concept check function a valid object instance, then you are fine). Other possibilities involve a lot of specializations and special cases, since the operator== can be implemented as a member operator of a class, as a binary operator in the class' namespace or some templated operator implementation (and many other cases as well). To take an address of such an operator function is not so easy or reliable. With Kind Regards, Ovanes Markarian
On Sun, July 22, 2007 16:26, Ovanes Markarian wrote:
Hi Martin,
if you simply would like to ensure that you compile a correct version, I would suggest the following solution:
A template function which compares a type instance with itself (makes no sense during the runtime since is always true, if there is a comparison operator, otherwise a compiler error is issued)
template<class Type_> inline void concept_comparison_exists(Type_ const& t) { static_cast<bool>(t==t); }
static_cast<bool>(t==t) is used to notify that compiler that this is an intended code and no warning should be produced.
Now some tests:
class SomeClassX //empty class to ensure that out concept works {};
int main(int argc, char* argv[]) {
int i = 8;
concept_comparison_exists(i); concept_comparison_exists(SomeClassX());
return 0; }
Just in addition to my post, if SomeClassX can be implicitly converted to some type which defines the operator==, the code will still compile fine. Here an example: class SomeClassX { public: operator int()const { return 0; } }; this line will produce NO error, since SomeClassX will be implicitly casted to int and int has the comparison operator. concept_comparison_exists(SomeClassX()); But in such a case you can't anyway assume what was the intention of the developer. So I would let it be valid. With Kind Regards, Ovanes
Martin Ecker
Hi,
Is there a way, using SFINAE tricks and potentially the techniques used in the Boost Concept Check Library, to detect at compile-time if a type T supports a certain expression? In my case, I'm interested if T supports operator ==. So I'm basically looking for a compile-time predicate so that this compiles:
struct my_struct { int i; }; struct my_struct2 { int i; }; bool operator == (my_struct2 const&, my_struct2 const&) const;
BOOST_STATIC_ASSERT((supports_comparison_operator<int>::value)); BOOST_STATIC_ASSERT((!supports_comparison_operator
::value)); BOOST_STATIC_ASSERT((supports_comparison_operator ::value));
This implementation is based on boost/detail/is_incrementable.hpp.
#include
participants (3)
-
Martin Ecker
-
Ovanes Markarian
-
Roman Perepelitsa