Ручной автоматический шаблон (без использования C ++ 0x) - PullRequest
8 голосов
/ 05 сентября 2010

Как реализовать функцию ключевого слова auto без использования стандарта c ++ 0x?

for(std::deque<std::pair<int, int> >::iterator it = points.begin();
    it != points.end(); ++it)
{
   ...
}

Может быть, такой класс:

class AUTO
{
public:
   template <typename T1>
   AUTO(T1);

   template <typename T2>
   operator T2();
};

При таком использовании:

for(AUTO it = points.begin(); it != points.end(); ++it)
{
   ...
}

Но T1 и T2 различны.Как перенести информацию о T1 в оператор T2 () ?Это действительно возможно?

Ответы [ 4 ]

12 голосов
/ 05 сентября 2010

Если бы расширение библиотеки было легко реализуемым, не было бы необходимости в расширении языка.См. N1607 для получения подробной информации об автоматическом предложении.

Тем не менее, статья в Boost.Foreach (что делает то, что вы хотите) макрос может помочь понять проблемы, связанные с такой реализацией.

Что такое BOOST_FOREACH?

В C ++ написание цикла, который повторяется в последовательности,утомительный.Мы можем либо использовать итераторы, которые требуют значительного количества вспомогательной таблицы, либо мы можем использовать алгоритм std :: for_each () и переместить наше тело цикла в предикат, что требует не меньшего количества вспомогательной таблицы и вынуждает нас перемещать нашилогика далеко не там, где будет использоваться.Напротив, некоторые другие языки, такие как Perl, предоставляют специальную конструкцию «foreach», которая автоматизирует этот процесс.BOOST_FOREACH как раз такая конструкция для C ++.Он перебирает последовательности для нас, освобождая нас от необходимости иметь дело непосредственно с итераторами или писать предикаты.

BOOST_FOREACH разработан для простоты использования и эффективности.Он не выполняет динамическое распределение, не выполняет виртуальные вызовы функций или вызовы через указатели функций и не делает вызовов, которые не прозрачны для оптимизатора компилятора.Это приводит к почти оптимальной генерации кода;производительность BOOST_FOREACH обычно находится в пределах нескольких процентов от эквивалентного кодированного вручную цикла.И хотя BOOST_FOREACH является макросом, он замечательно хорошо себя ведет.Он оценивает свои аргументы ровно один раз, что не приводит к неприятным сюрпризам.

10 голосов
/ 05 сентября 2010

Существует макрос BOOST_AUTO , который более или менее выполняет то, что выполняет ключевое слово auto ... Однако один взгляд на его реализацию скажет вам, что гораздо лучше найти способ использовать C ++ 0x:>

3 голосов
/ 11 сентября 2010

Эти макросы можно использовать для обхода этого стандартным образом.

#define DEF_DED(D, E) any_base const & D = make_any_concrete((E))
#define DED(D, E) get_t(D, true ? ded_ty() : get_idt((E)))

template<typename T> struct id {
  typedef T type;
};

template<typename T>
id<T> get_idt(T t) { return id<T>(); }

struct any_base { };

template<typename D>
struct any_concrete : any_base {
  any_concrete(D d):d(d) {}
  mutable D d;
};

template<typename T>
any_concrete<T> make_any_concrete(T x) { return any_concrete<T>(x); }

struct ded_ty {
  template<typename T>
  operator id<T>() { return id<T>(); }
};

template<typename T>
T &get_t(any_base const &b, id<T>) { return static_cast<any_concrete<T> const&>(b).d; }

Таким образом, ваш цикл for становится

for(DEF_DED(it, points.begin()); 
    DED(it, points.begin()) != points.end(); 
  ++DED(it, points.begin()))
{
   ...
}

Кредит переходит к Условная любовь: FOREACH Redux , Эрик Ниблер. Не уверен, действительно ли это того стоит:)

2 голосов
/ 06 сентября 2010

Более неотложная проблема - получить информацию от выведенного типа к объявлению члена данных.

class AUTO
{
public:
   template <typename T1>
   AUTO(T1);

   T1 state; // eg deque<...>::iterator - need this!
};

Это явно не произойдет, потому что объект AUTO должен быть размещен до вызова функции..

Учитывая typeof или decltype, это не так сложно, хотя.

#define AUTO( name, initializer ) typeof( initializer ) name = initializer

Конечно, это имеет много ограничений.И typeof не является стандартным.С поддержкой нескольких компиляторов это, вероятно, будет основой для этих инструментов Boost.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...