views:

157

answers:

4

Is there anyways to have a define increment every time you use it?

For example

int a = ADEFINE;
int b = ADEFINE;

a is 1 and b is 2.

+3  A: 
static int PUT_AN_UNUSED_NAME_HERE = 0;
#define ADEFINE (++PUT_AN_UNUSED_NAME_HERE)
KennyTM
This isn't compile time, though.
GMan
+8  A: 

You can use __COUNTER__, though it's not standard. Both MSVC++ and GCC support it.


If you can use boost, the pre-processor library has an implementation of counter. Here's the example from the documentation:

#include <boost/preprocessor/slot/counter.hpp>

BOOST_PP_COUNTER // 0

#include BOOST_PP_UPDATE_COUNTER()

BOOST_PP_COUNTER // 1

#include BOOST_PP_UPDATE_COUNTER()

BOOST_PP_COUNTER // 2

#include BOOST_PP_UPDATE_COUNTER()

BOOST_PP_COUNTER // 3

(Kudo's to gf)

GMan
Although this doesn't affect the asker, one should note that `__COUNTER__` only works for GCC ≥4.3. (Xcode, for instance, only bundles with GCC 4.2.)
KennyTM
I just noticed that Boost.Preprocessor provides a portable version of `__COUNTER__` (kind of): http://www.boost.org/doc/libs/1_41_0/libs/preprocessor/doc/index.html
Georg Fritzsche
@gf: Thanks, I'll add that.
GMan
+2  A: 

If you don't need compile-time-constants, you could do something like this to enumerate classes:

int counter() {
    static int i = 0;
    return i++;
}

template<class T>
int id() { 
    static int i = counter();
    return i; 
};

class A {};
class B {};

int main()
{
    std::cout << id<A>() << std::endl;
    std::cout << id<B>() << std::endl;
}
Georg Fritzsche
+1  A: 

Why not use __LINE__? It's standard C89/C99/C++.

Drew Hall
Because `a` and `b` maybe both on line 14 in different files?
KennyTM