2010-02-24 2 views
6

В настоящее время я использую следующий шаблон просто как способ проверки указателя NULL, и если NULL затем распечатает сообщение об ошибке в файле журнала и затем вернет false.Пропустить переменную «name» в C++

template< typename T > 
static bool isnull(T * t, std::string name = "") 
{ 
    _ASSERTE(t != 0); 
    if(!t) 
    { 
     if(!(name.length())) name = "pointer"; 
     PANTHEIOS_TRACE_ERROR(name + " is NULL"); 
     return false; 
    } 
    return true; 
} 

В настоящее время я называю это следующим образом:

if(!(isnull(dim, BOOST_STRINGIZE(dim)))) return false; 

Если вы заметили, мне нужно передать в «имя» указателя-переменной, которую я хочу, чтобы напечатать в файл журнала, так как Второй параметр. В настоящее время я использую BOOST_STRINGIZE, который просто преобразует любой текст в круглые скобки в строку.

Ниже приведены недостатки моей реализации шаблона (для моего использования, по крайней мере)

  • Любой мог пройти в чем-либо в качестве параметра BOOST_STRINGIZE распечатать в лог-файл - так как 2 параметра не связаны в любом случае - поэтому я не обязательно буду видеть «имя переменной», которое на самом деле равно NULL.
  • Мы должны помнить, что нужно передать второй параметр, иначе бесполезный.

В любом случае, я могу определить «имя» этой 1-й переменной, чтобы я мог пропускать ее, как 2-й параметр, с каждым вызовом?

+1

Если вы не используете препроцессорную магию, это невозможно. , но Вы всегда можете написать: '#define IS_NULL (a) isnull ((a), #a)' – lollinus

+1

Вторая проблема может быть решена, просто избавившись от значения по умолчанию в параметре имени. Только касательная связь с использованием «name.empty()» может быть более быстрой и/или более четкой, чем «! Name.length()» –

+0

@ Mark-B. Спасибо за «пустой» комментарий :). Я думаю, что я просто предположил, что поскольку vector.empty() фактически вызывает size() (в реализации VC++ 2005), он, вероятно, был таким же для строк. Плохой оссанд-кад. – ossandcad

ответ

9

Вы можете поместить все это в одном макросе:

#define IS_NULL(name_) isnull(name_, #name_) 

Обратите внимание, что BOOST_STRINGIZE расширяет свой аргумент, если его макрос, который может или не может быть то, что вы хотите:

#define X(x_) std::cout << BOOST_STRINGIZE(x_) << " = " << x_ << std::endl; 
X(NULL); // prints: "0 = 0" 
+0

Вы хотите подчеркнуть макрос как 'BOOST_STRINGIZE', или он всегда будет передавать« имя_ ». – GManNickG

+1

Как так, '#' stringifies 'name_'? Разница 'BOOST_STRINGIZE' заключается только в том, что она расширяет' name_', если это макрос, который я не обязательно считаю преимуществом. :) –

+0

Я думал о чем-то другом: 3 Оба моих комментария загадочно исчезнут в неуточненное время. – GManNickG

1

Конечно, почему нет:

#define new_isnull(x) isnull(x, BOOST_STRINGIZE(x)) 
+0

Спасибо. использование # вместо BOOST_STRINGIZE было преимуществом принятого ответа. – ossandcad

1

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

//if(!(isnull(dim, BOOST_STRINGIZE(dim)))) return false; 
#define ISNULL(a) isnull((a), #a) 
if (!ISNULL(dim)) return false; 

Обратите внимание, что, как всегда, макросы имеют ряд недостатков, связанных с ними.

Смежные вопросы