Вопрос

Есть ли в Microsoft Visual C ++ 2008, аналогичный стандартизированным auto или decltype в C ++ 0x?

Это было полезно?

Решение

Нет, ничего подобного, стандартный ни поставщик конкретный ни аддона. Вам придется обновить до VS2010, он реализует авто.

Другие советы

Цитируя из А. Усилить список рассылки Статья Arkadiy Vertreyb:

Бог только знает, что еще можно найти внутри этого компилятора, если кто-то готов копать очень глубоко.

Например, Игорь Чесноков из RSDN (российская сеть разработчиков программного обеспечения) нашла способ реализации TypeOf (), который не требует регистрации, и, вероятно, имеет показатели компиляции второго типа.

Как? По-видимому, какая-то странная «функция» Visual C ++ позволила ему перевести его в Twick тело шаблона в момент создания присмотров, когда доступен дополнительный контекст, таким образом «регистрация» классов на лету, в момент принятия типов ().

Специфичные Microsoft «Bugfeatures», как правило, не в области моих интересов. Однако я понимаю, что на компиляторе 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;
}

Теперь я не пробовал этот код, и, поскольку он использует Commital-Special Parts, отметить, что это для MSVC 7.x. Так что это может не работать с более поздней версией. Надеюсь, это делает?

Ура и хет.,

Использовать повышение. Или, если вы не хотите поссорить все усилие, вот фрагмент, который будет работать с Visual Studio 2008 (но, вероятно, нет другой версии):

namespace typeid_detail {

template <int N>
struct encode_counter : encode_counter<N - 1> {};

template <>
struct encode_counter<0> {};

char (*encode_index(...))[5];
// need to default to a larger value than 4, as due to MSVC's ETI errors. (sizeof(int) = 4)

struct msvc_extract_type_default_param {};

template <typename ID, typename T = msvc_extract_type_default_param>
struct msvc_extract_type;

template <typename ID>
struct msvc_extract_type<ID, msvc_extract_type_default_param> {
    template <bool>
    struct id2type_impl;

    typedef id2type_impl<true> id2type;
};

template <typename ID, typename T>
struct msvc_extract_type : msvc_extract_type<ID,msvc_extract_type_default_param> {
    template <>
    struct id2type_impl<true> { // VC8.0 specific bugfeature
        typedef T type;
    };

    template <bool>
    struct id2type_impl;

    typedef id2type_impl<true> id2type;
};

template <typename T, typename ID>
struct msvc_register_type : msvc_extract_type<ID, T> {
};

template <int i>
struct int_ {
    enum { value = i };
};

template <int ID>
struct msvc_typeid_wrapper {
    typedef typename msvc_extract_type<int_<ID> >::id2type id2type;
    typedef typename id2type::type type;
};

template <>
struct msvc_typeid_wrapper<1> {
    typedef msvc_typeid_wrapper<1> type;
};
// workaround for ETI-bug for VC6 and VC7

template <>
struct msvc_typeid_wrapper<4> {
    typedef msvc_typeid_wrapper<4> type;
};
// workaround for ETI-bug for VC7.1

#define TYPEOF_INDEX(T) (sizeof(*encode_index((encode_counter<405/*1005*/>*)0))) // this needs to be lower for VS 2008, otherwise causes too deep templates
#define TYPEOF_NEXT_INDEX(next) friend char (*encode_index(encode_counter<next>*))[next];

template <typename T>
struct encode_type {
    static const unsigned value = TYPEOF_INDEX(T);
    // get the next available compile time constants index

    typedef typename msvc_register_type<T,int_<value> >::id2type type;
    // instantiate the template

    static const unsigned next = value + 1;
    // set the next compile time constants index

    TYPEOF_NEXT_INDEX(next);
    // increment the compile time constant (only needed when extensions are not active)
};

template <class T>
struct sizer {
    typedef char(*type)[encode_type<T>::value];
};

template <typename T> typename sizer<T>::type encode_start(T const&);
// a function that converts a value to size-encoded type (not implemented, only needed for type inference)

template <typename Organizer, typename T>
msvc_register_type<T, Organizer> typeof_register_type(const T&, Organizer* = 0);

} // ~typeid_detail

#define type_of(expr) \
    typeid_detail::msvc_typeid_wrapper<sizeof(*typeid_detail::encode_start(expr))>::type

И использовать, например, как:

int x = 123;
float y = 456.0f;
typedef type_of(x+y) int_plus_float;
int_plus_float value = x + y;

И, конечно, обратитесь к Boost License при использовании этого.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top