Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
template_metaprogramming_ru.docx
Скачиваний:
12
Добавлен:
01.07.2025
Размер:
774 Кб
Скачать
☆

Исправленный пример:

struct nil {};

template <class H, class T = nil>

struct node

{

typedef H head; typedef T tail;

};

template <class S>

struct total_size

{

typedef typename total_size<

typename S::tail

>::type tail_size;

typedef boost::mpl::int_<

sizeof(S::head)

+ tail_size::value

> type;

};

// Добавление частичной специализации для завершения рекурсии:

template <class H>

struct total_size<node<H, nil>>

{

typedef H tail_size;

typedef boost::mpl::int_<sizeof(H)> type;

};

int main(int argc, char* argv[])

{

typedef node<char, node<int, node<float, node<String>>>> l;

auto size = total_size<l>::type::value;

cout << size << endl;

return 0;

}

Форматы сообщений об ошибках

Несмотря на различие компиляторов, есть некоторые общности в их сообщениях об ошибках.

Исследуем диагностику, произведенную тремя различными компиляторами для следующего примера:

#include <map>

#include <list>

#include <iterator>

#include <string>

#include <algorithm>

using namespace std;

void copy_list_map(list<string> & l, map<string, string>& m)

{

std::copy(l.begin(), l.end(), std::back_inserter(m));

}

Несмотря на простоту кода, некоторые компиляторы выдают для него очень масштабные сообщения об ошибках (MSVC6):

C:\PROGRA~1\MICROS~4\VC98\INCLUDE\xutility(19) : error C2679:

binary '=' : no operator defined which takes a right-hand operand

of type 'class std::basic_string<char,struct std::char_traits<

char>,class std::allocator<char> >' (or there is no acceptable

conversion)

foo.cpp(9) : see reference to function template

instantiation 'class std::back_insert_iterator<class std::

map<class std::basic_string<char, struct std::char_traits<

char>,class std::allocator<char> >,class std::basic_string<

char,struct std::char_traits<char>,class std::allocator<char

> >,struct std::less<class std::basic_string<char,struct std

::char_traits<char>,class std::allocator<char> > >,class std

::allocator<class std::basic_string<char,struct std::

char_traits<char>,class std::allocator<char> > > > > __cdecl

std::copy(class std::list<class std::basic_string<char,

struct std::char_traits<char>,class std::allocator<char> >,

class std::allocator<class std::basic_string<char,struct std

::char_traits<char>,class std::allocator<char> > > >::

iterator,class std::list<class std::basic_string<char,struct

std::char_traits<char>,class std::allocator<char> >,class

std::allocator<class std::basic_string<char,struct std::

char_traits<char>,class std::allocator<char> > > >::iterator

,class std::back_insert_iterator<class std::map<class std::

basic_string<char,struct std::char_traits<char>,class std::

allocator<char> >,class std::basic_string<char,struct std::

char_traits<char>,class std::allocator<char> >,struct std::

less<class std::basic_string<char,struct std::char_traits<

char>,class std::allocator<char> > >,class std::allocator<

class std::basic_string<char,struct std::char_traits<char>,

class std::allocator<char> > > > >)' being compiled

message continues...

typedef

Длинные типы, наподобии следующего

class std::basic_string<char, struct std::char_traits<char>,class std::allocator<char>>

часто повторяются в выводах, наршуая общую читабельность сообщений. Если выполнить замену данного «внутреннего» типа на переопределенный string, то сообщение об ошибке примет следующий вид:

C:\PROGRA~1\MICROS~4\VC98\INCLUDE\xutility(19) : error C2679:

binary '=' : no operator defined which takes a right-hand operand

of type 'std::string' (or there is no acceptable conversion)

foo.cpp(9) : see reference to function template instantiation

'class std::back_insert_iterator<class std::map<std::string,

std::string,struct std::less<std::string>,class

std::allocator<std::string> > > __cdecl std::copy(class

std::list<std::string,class std::allocator<std::string>

>::iterator,class std::list<std::string,class std::allocator<

std::string> >::iterator,class std::back_insert_iterator<

class std::map<std::string,std::string,struct std::

less<std::string>,class std::allocator<std::string> > >)'

being compiled

Так сообщение выглядит боллее читабельным. Последние версии GCC делаеют такие преобразования к синонимам для всех переопределенных типов автоматически (в MSVC10 такие замены также происходят):

...continued messages

/usr/include/c++/3.2/bits/stl_algobase.h:228: no match for '

std::back_insert_iterator<std::map<std::string, std::string,

std::less<std::string>, std::allocator<std::pair<const

std::string, std::string> > > >& = std::basic_string<char,

std::char_traits<char>, std::allocator<char> >&' operator

messages continue...

При этом GCC не сделал замену правого операнда в в операции присваивания и в этом есть смысл.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]