473,835 Members | 1,872 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Member function existence queries...

How (at compile time) can one determine whether some class implements
a particular member function? Name only is sufficient, full signature
match nice but not required.

The application is a template class that (among other things) defines
an iterator class. The category of iterator depends on the template
argument type: if the argument defines only operator++ then the
iterator will be a forward_iterato r, but if it also defines operator--
then the created iterator should be a bidirectional_i terator. That is,
something like this psudocode:

template<typena me T> class Foo {
public:
typedef ("T defines --" ? bidirectional_i terator :
forward_iterato r) Cat;
class iter : public iterator<..., ..., Cat, ...> {...}
};

The obvious approach is to specialize on the type of T. Unfortunately,
this code is in a general purpose library and the types that might be
the arguments are unknown and probably don't exist yet.

A second obvious approach is to require that the correct
iterator_catego ry be passed in as an explicit argument. Unfortunately,
the requirement for the category is a long way from the library user
interface and asking the user to understand the need and correct value
for this extra argument would be a bit much.

A third approach would be to simply define the richest iterator
category and let it blow up if the actual type did not support
something the user tried to do. Unfortunately other code (STL for
example) will be specialized on the category of the iterators and so
will blow up if wrongly categorized even though it would work with the
correct categorization.

The Boost etc. constraint checking approaches don't work here: they
check for the presence of a concept, but give a compile error if it is
missing, whereas I accept missing without error but want to do
something different in that case.

I have tried to come up with a metaprogram that would do the necessary
test, and failed. The most promising approach was to create a class
that inherited from both the argument T and also from a dummy class
that does define operator-- but with a unique result type. Then a
"typeof(--TEST())" would be either whatever T's operator-- returned,
or the unique dummy type, and the two could be discriminated by
specialization. However, this approach fails because the compiler
throws an ambiguity error when both T and DUMMY have operator--. I
have not been able to create an inheritance tree that forces the
overloading inheritance rules to only pick T (if it has one) without
an ambiguity - ideas?

This cannot be a new problem - how do you do it?

Ivan
Jul 19 '05 #1
2 2355
On 3 Sep 2003 16:31:19 -0700, ig*****@pacbell .net (Ivan) wrote:
How (at compile time) can one determine whether some class implements
a particular member function? Name only is sufficient, full signature
match nice but not required.

The application is a template class that (among other things) defines
an iterator class. The category of iterator depends on the template
argument type: if the argument defines only operator++ then the
iterator will be a forward_iterato r, but if it also defines operator--
then the created iterator should be a bidirectional_i terator. That is,
something like this psudocode:

template<typen ame T> class Foo {
public:
typedef ("T defines --" ? bidirectional_i terator :
forward_iterat or) Cat;
class iter : public iterator<..., ..., Cat, ...> {...}
};

I have tried to come up with a metaprogram that would do the necessary
test, and failed. The most promising approach was to create a class
that inherited from both the argument T and also from a dummy class
that does define operator-- but with a unique result type. Then a
"typeof(--TEST())" would be either whatever T's operator-- returned,
or the unique dummy type, and the two could be discriminated by
specialization . However, this approach fails because the compiler
throws an ambiguity error when both T and DUMMY have operator--. I
have not been able to create an inheritance tree that forces the
overloading inheritance rules to only pick T (if it has one) without
an ambiguity - ideas?

This cannot be a new problem - how do you do it?


This worked on Comeau - good luck making it work on anything else (it
should be possible on gcc with a few changes). I've not seen it
elsewhere (although it just uses SFINAE), but I can't believe it's the
first implementation. ..

#include <iterator>

typedef char yes;
typedef char (&no)[2];

template <bool b, typename T1, typename T2>
struct select
{
typedef T1 type;
};

template <typename T1, typename T2>
struct select<false, T1, T2>
{
typedef T2 type;
};

template <class T>
struct itcat
{
private:
template <class U, U&(U::*Ptr)() = &U::operator-->
struct decrtester;

template <class U>
static no decrtest(...);

template <class U>
static yes decrtest(decrte ster<U>*);

static bool const has_decr = sizeof(yes) ==
sizeof(decrtest <T>(0));

public:
typedef typename select<has_decr ,
std::bidirectio nal_iterator_ta g,
std::forward_it erator_tag>::ty pe type;
};

struct It1
{
It1& operator--(){
return *this;
}
};

struct It2
{
};

#include <iostream>
#include <typeinfo>

int main()
{
std::cout << typeid(itcat<It 1>::type).name( ) << '\n';
std::cout << typeid(itcat<It 2>::type).name( ) << '\n';
}

Tom
Jul 19 '05 #2
ig*****@pacbell .net (Ivan) writes:
How (at compile time) can one determine whether some class implements
a particular member function? Name only is sufficient, full signature
match nice but not required.

The application is a template class that (among other things) defines
an iterator class. The category of iterator depends on the template
argument type: if the argument defines only operator++ then the
iterator will be a forward_iterato r, but if it also defines operator--
then the created iterator should be a bidirectional_i terator. That is,
something like this psudocode:

template<typena me T> class Foo {
public:
typedef ("T defines --" ? bidirectional_i terator :
forward_iterato r) Cat;
class iter : public iterator<..., ..., Cat, ...> {...}
};


The following should do what you want:

<SNIP>

/** check at compile time, if function foo exists in given class.
* taken from postings in the boost mailing list
*/
#include <iostream>
//#include "boost/ref.hpp" // for BOOST_STATIC_CO NSTANT
//#include "boost/static_assert.h pp" // for BOOST_STATIC_AS SERT

#define BOOST_STATIC_AS SERT( B ) \
enum { BOOST_JOIN(boos t_static_assert _enum_, __LINE__) \
= sizeof(::boost: :STATIC_ASSERTI ON_FAILURE< (bool)( B ) >) }

#define BOOST_STATIC_CO NSTANT(type, assignment) enum { assignment }
typedef char (&no_tag)[1];
typedef char (&yes_tag)[2];

template< typename T > no_tag has_member_foo_ helper(...);

// template< typename T >
// yes_tag has_member_foo_ helper(int, void (T::*)() = &T::foo);

template < typename T, void (T::*)() > struct ptmf_helper {};

template< typename T >
yes_tag has_member_foo_ helper(int, ptmf_helper<T, &T::foo>* p = 0);

template< typename T >
struct has_member_foo
{
BOOST_STATIC_CO NSTANT(bool
, value = sizeof(has_memb er_foo_helper<T >(0)) == sizeof(yes_tag)
);
};

struct my {};
struct her { void foo(); };
int main()
{
//BOOST_STATIC_AS SERT(!has_membe r_foo<my>::valu e);
//BOOST_STATIC_AS SERT(has_member _foo<her>::valu e);
std::cout << "has_member_foo (my): " << has_member_foo< my>::value << "\n";
std::cout << "has_member_foo (her): " << has_member_foo< her>::value << "\n";
return 0;
}

<SNAP>

But beware, some (many?) compilers won't compile this at all - I tried it
with MSVC 7.1, Comeau online, GCC 3.2.1 and Intel 7.0 - only MSVC and
Comeau compiled it.

HTH & kind regards
frank

--
Frank Schmitt
4SC AG phone: +49 89 700763-0
e-mail: frank DOT schmitt AT 4sc DOT com
Jul 19 '05 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

15
8067
by: Wolfram Humann | last post by:
Hi, please don't be too harsh if I made stupid errors creating this simple example from my more complex case. Suppose I have a class like this: class BOOK { const string title;
37
5038
by: Ben | last post by:
Hi, there. Recently I was working on a problem where we want to save generic closures in a data structure (a vector). The closure should work for any data type and any method with pre-defined signature. When developing this lib, I figured that the pointer-to-member-function, although seemingly an attractive solution, does not work well for us.
6
1826
by: amit.bhatia | last post by:
Hi, I have also posted this to the moderated group. I have 2 classes A and B, what does the following mean in header file for class A: class A { class B &b; .... };
40
3052
by: Steve Rencontre | last post by:
I can't for the life of me see how to do pointer-to-member when the member is actually part of an embedded structure. That is, if I have: struct S1 { int a; }; struct S2 { S1 s; int b; }; how can I get a pointer to the a in an S2?
6
1401
by: 2005 | last post by:
Hi I have initialized a member as below: class CNode { public: CNode() : m_pNext(0), m_ticketNum(0) {} ---- private: int m_ticketNum; // ticket number of car CarNode *m_pNext;
7
3230
by: VK | last post by:
I was getting this effect N times but each time I was in rush to just make it work, and later I coudn't recall anymore what was the original state I was working around. This time I nailed the bastard so posting it before I forgot again... By taking this minimum code: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <html> <head>
12
540
by: WaterWalk | last post by:
Hello. I am rather confused by the type of a pointer to class data member. Many c++ texts say that pointer to data member has a special syntax. For example the following class: class MyClass { public: int n; }; The pointer to MyClass.n shall be defined like this:
6
3885
by: Olumide | last post by:
Hi - I've got a class that contains static member functions alone, all of whose arguments are passed by reference as shown below: class MySpiffyClass{ // no constructor, destructor or variables, just static members static void FirstFunction( args & ); static void SecondFunction( args & ); static void ThirdFunction( args & );
2
1637
by: bruestle | last post by:
I've been working on improving my javascript coding and decided to start using classes. I've gotten pretty far but am having problems attaching a member function to a control event. CBonfireStore.prototype.setupClick = function( obj ) { obj.onclick = function(){ this.incrementClicked(obj); }; obj.style.cursor = 'pointer'; }
0
9810
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9653
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10815
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10524
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9348
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7768
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5805
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4434
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
3092
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.