Pull to refresh

STL Filter — скрипт для лаконичных ошибок STL

Reading time3 min
Views1.7K
STL славится своей способностью заполнять метры экранного пространства сообщениями об ошибках. Надоело смотреть на экран и видеть перлы вроде:

testmap.cpp:25: error: no matching function for call to ‘std::map<int, double, std::less, std::allocator<std::pair<const int, double> > >::map(int, int, int)’
/usr/include/c++/4.3/bits/stl_map.h:175: note: candidates are: std::map<_Key, _Tp, _Compare, _Alloc>::map(const std::map<_Key, _Tp, _Compare, _Alloc>&) [with _Key = int, _Tp = double, _Compare = std::less, _Alloc = std::allocator<std::pair<const int, double> >]
/usr/include/c++/4.3/bits/stl_map.h:165: note: std::map<_Key, _Tp, _Compare, _Alloc>::map(const _Compare&, const _Alloc&) [with _Key = int, _Tp = double, _Compare = std::less, _Alloc = std::allocator<std::pair<const int, double> >]


ну и еще пара десятков строк.



Решение проблемы длиннющих ошибок заключается в том чтобы использовать фильтры вывода STL. Об одном таком фильтре, stlfilt, рассказал Скотт Мейерс в своей книге Effective STL.

Пример использования


Имеем код с ошибками в использовании std::map:
#include <iostream>
#include <map>
#include <algorithm>
#include <cmath>
using namespace std;

const int values[] = { 1,2,3,4,5 };
const int NVALS = sizeof values / sizeof (int);

struct intComp: public binary_function<int, int, bool>
{
  bool operator()(int a, int b) const
  {
    return a < b;
  }
};

int main()
{
  using namespace std;

  typedef map<int, double> valmap;
  typedef map<int *, double *> pmap;
  
  valmap m2(1,2,3);
  pmap m3(1,2,3);
  map<int, double, intComp> valmap3;

  valmap m;
  pmap p;
  
  for (int i = 0; i < NVALS; i++)
  {
    m.insert(make_pair(values[i], pow(values[i], .5)));
    valmap3.insert(0);
  }

  valmap::iterator it = 100;
  valmap::const_iterator cit = 100;
  
  m.insert(1,2);
  m.insert(make_pair(36, 10.57)); // fine, more convenient
  m.insert(m.end(), make_pair(40, 2.29)); // also fine
  return 0;
}

* This source code was highlighted with Source Code Highlighter.


вместо g++ testmap.cpp выполняем gfilt testmap.cpp. Результат:
testmap.cpp: In function ‘int main()’:
testmap.cpp:25: error: No match for ‘map<int, double>::map(int, int, int)’
testmap.cpp:26: error: No match for ‘map<int *, double *>::map(int, int,
int)’
testmap.cpp:35: error: No match for ‘map<int, double, intComp>::insert(
int)’
testmap.cpp:38: error: conversion from ‘int’ to non-scalar type ‘gen_map<
int, double>::iterator’ requested
testmap.cpp:39: error: conversion from ‘int’ to non-scalar type ‘gen_map<
int, double>::const_iterator’ requested
stl_tree.h: In member function ‘void map<
int, double>::_M_insert_unique(_II, _II)’:
[STL Decryptor: Suppressed 1 more STL standard header message]
testmap.cpp:41: instantiated from here
stl_tree.h:1295: error: invalid type argument of ‘unary *’

На мой взгляд, это выглядит куда симпатичнее.

Установка


Установка и настройка проста:
  • скачать STLFilt
  • распаковать архив
  • в скрипте-оболочке gfilt написать COMPILER=g++. Мне еще не нравится использование less при выводе, убрать его из переменной PAGER.
  • Все, теперь оболочка передает все ключи g++, принимает от него информацию об ошибках. парсит её и выдает нам.
Tags:
Hubs:
Total votes 40: ↑32 and ↓8+24
Comments35

Articles