В зависимости от суммы почты Вы отправляете, Вы могли бы хотеть изучить использование реального почтового сервера как postifx или sendmail (*nix системы), Обе из тех программ имеют способность отправить полученную почту в программу на основе адреса электронной почты.
Нет, это не так. Препроцессор не имеет ничего общего с обработкой шаблонов, которую выполняет компилятор. Шаблоны не генерируют код C ++, как и вызов функции - они являются неотъемлемой частью самого языка C ++.
Неа, в общем, нельзя. Шаблоны - это просто часть языка C ++, они не являются отдельным препроцессором, поэтому они не генерируют код C ++.
Обычное решение - добавить в код статические утверждения и другие тесты, чтобы убедиться, что правильные шаблоны
Как только вы начнете теряться в метапрограммировании, этот простой трюк поможет вам определить, к какому типу на самом деле относится параметр шаблона:
// given a variable t of an unknown type T
int*** i = t;
Когда компилятор обнаруживает это, он распечатывает красивый и простое сообщение об ошибке «Невозможно преобразовать <длинное, подробное имя_типа>
в int ***», позволяющее легко проверить, что параметр шаблона T действительно соответствует типу, который, по вашему мнению, должен быть.
Это потенциально ответ на ваш вопрос:
Инструмент препроцессора шаблонов C ++
Кажется, удовлетворил последнего, кто спросил - хотя я не могу представить, почему! Вывод компилятора C ++ на C обычно довольно нечитабелен, потому что он не предназначен для помощи в понимании, это просто своего рода переносимый язык ассемблера.
вообще невозможно вывести весь код. Но что я нашел чрезвычайно интересным, так это возможность использовать отладчик Visual C ++, чтобы показать вам тип. Возьмите эту простую мета-программу:
template<class Head, class Tail>
struct type_list
{
typedef Head head;
typedef Tail tail;
};
struct null_type
{};
template<class List>
struct list_head
{
typedef typename List::head head;
};
template<class List>
struct list_tail
{
typedef typename List::tail tail;
};
template<class List>
struct list_length
{
static const size_t length = 1+list_length< typename list_tail<List>::tail >::length;
};
template<>
struct list_length<null_type>
{
static const size_t length = 0;
};
int main()
{
typedef
type_list
< int
, type_list
< double
, type_list
< char
, null_type
>
>
> my_types;
my_types test1;
size_t length=list_length<my_types>::length;
list_head<list_tail<list_tail<my_types>::tail>::tail>::head test2;
}
Я только что создал экземпляры своих мета-типов. Это все еще пустые экземпляры классов C ++ длиной не менее 1 байта. Теперь я могу поставить точку останова после последнего экземпляра test2 и посмотреть, какие типы / значения длины, test1 и test2 имеют:
Вот что показывает отладчик:
length 3 unsigned int
test1 {...} type_list<int,type_list<double,type_list<char,null_type> > >
test2 -52 'Ì' char
Теперь вы знаете, что голова вернула вам символ , ваш список содержит int, double, char и завершается null_type.
Это мне очень помогло. Иногда вам нужно скопировать действительно беспорядочный шрифт в текстовый редактор и отформатировать его в удобочитаемую форму, но это дает вам возможность отследить, что находится внутри и как оно рассчитывается.
Надеюсь, это поможет, Ованес
Проверьте мою публикацию об отладке метапрограмм шаблона C ++
На странице 6 вы можете увидеть, как это работает. Для конкретных целей вам не понадобится весь набор инструментов, это можно сделать вручную.
Я создал надстройку Visual C ++, в которой вы могли бы размещать точки останова и т. Д., Но это было скорее доказательством концепции, чем инструментом для повседневного использования.
Мы работали над графическим интерфейсом, который показывает все экземпляры, позволяет отладку и профилирование. К сожалению, мы не можем обещать дату публикации этого инструмента, так как делаем это в наше довольно ограниченное свободное время.
ОБНОВЛЕНИЕ: отладчик и профилировщик доступны здесь
ОБНОВЛЕНИЕ: Презентация C ++ Now