Цитирование из списка рассылки Boost Статья Аркадия Вертлейба:
Бог знает только, что еще можно найти
внутри этого компилятора, если кто-то готов
копать очень глубоко.
Например, Игорь Чесноков из RSDN
(Российская сеть разработки программного обеспечения)
нашел способ реализовать typeof ()
что не требует регистрации,
и, вероятно, имеет время компиляции
выступление родного typeof.
Как? Видимо, какая-то странная «фича»
Visual C ++ позволил ему тикать
тело шаблона на момент
экземпляр, когда дополнительный контекст
имеется, таким образом, "регистрация"
занятия на лету, в момент
взятие typeof ().
Специфичные для Microsoft «ошибки»
как правило, не в области моего
интересы. Однако я понимаю, что
на компиляторе Microsoft, это может
выглядеть намного привлекательнее
все, что Педер и я реализовали.
И хотя я понимаю, что это
может быть серьезная конкуренция, я
будет очень плохо, не говоря уже
это здесь:
http://rsdn.ru/Forum/?mid=1094305
И цитирование кода Игоря Чеснокова со страницы, на которую ссылается цитируемая ссылка выше:
// type_of() evil implementation for VC7
//
// (c) Chez
// mailto:chezu@pisem.net
#include "stdafx.h"
// This file contains:
// 1) type_id(type)
// 2) var_type_id(expersssion)
// 3) type_of(expression)
// IMPLEMENTATION
template<int ID>
class CTypeRegRoot
{
public:
class id2type;
};
template<typename T, int ID>
class CTypeReg : public CTypeRegRoot<ID>
{
public:
class CTypeRegRoot<ID>::id2type // This uses nice VC6-VC7 bugfeature
{
public:
typedef T Type;
};
typedef void Dummy;
};
template<int N>
class CCounter;
// TUnused is required to force compiler to recompile CCountOf class
template<typename TUnused, int NTested = 0>
class CCountOf
{
public:
enum
{
__if_exists(CCounter<NTested>) { count = CCountOf<TUnused, NTested + 1>::count }
__if_not_exists(CCounter<NTested>) { count = NTested }
};
};
template<class TTypeReg, class TUnused, int NValue> // Helper class
class CProvideCounterValue
{
public:
enum { value = NValue };
};
// type_id
#define type_id(type) \
(CProvideCounterValue< \
/*register TYPE--ID*/ typename CTypeReg<type, CCountOf<type >::count>::Dummy, \
/*increment compile-time Counter*/ CCounter<CCountOf<type >::count>, \
/*pass value of Counter*/CCountOf<type >::count \
>::value)
// Lets type_id() be > than 0
class __Increment_type_id { enum { value = type_id(__Increment_type_id) }; };
template<int NSize>
class sized
{
private:
char m_pad[NSize];
};
template<typename T>
typename sized<type_id(T)> VarTypeID(T&);
template<typename T>
typename sized<type_id(const T)> VarTypeID(const T&);
template<typename T>
typename sized<type_id(volatile T)> VarTypeID(volatile T&);
template<typename T>
typename sized<type_id(const volatile T)> VarTypeID(const volatile T&);
// Unfortunatelly, var_type_id() does not recognize references
#define var_type_id(var) \
(sizeof(VarTypeID(var)))
// type_of
#define type_of(expression) \
/* This uses nice VC6-VC7 bugfeature */ \
CTypeRegRoot<var_type_id(expression)>::id2type::Type
// auto_operator
#define auto_operator(arg1, arg2, op) \
type_of(instance(arg1) op instance(arg2)) operator op
// TEST
class A
{
public:
friend static const char* operator +(const A& a, const A& b)
{
return "chijik-pijik";
}
};
template<typename T>
class Plus
{
public:
friend static type_of(T() + T()) operator +(const Plus<T>& a, const Plus<T>& b)
{
return a.m + b.m;
}
T m;
};
int _tmain(int argc, _TCHAR* argv[])
{
Plus<A> a1, a2;
const char* x = a1 + a2;
return 0;
}
Теперь я не пробовал этот код, и, поскольку он использует специфичные для компилятора вещи, обратите внимание, что он предназначен для MSVC 7.x. Так что это может или не может работать с более поздней версией. Надеюсь, это так?
Приветствия и hth.,