2010-11-11 4 views
2

Im просматривает некоторый код из библиотеки Loki, в которой много отливок C-стиля. У меня есть некоторые сомнения в необходимости этих бросков в первую очередь, и если они необходимы, если я часто не могу сделать код более безопасным, заменив их static_cast. Однако, если единственная «особенность» последнего - загромождать экран с уродливым кодом, я бы предпочел.Удивление о преимуществах этих стилей C-стиля

Проблема с приведениями в библиотечном коде вроде этого заключается в том, что, если вы действительно не уверены в себе, их трудно удалить, потому что почему они были там в первую очередь? Может быть, они были введены, чтобы избежать некоторых предупреждений компилятора на каком-то компиляторе, что я не буду тестировать ....

Так что я задаю несколько мнений.

Ниже приведены некоторые основные фрагменты кода, в которых должны быть самые важные объявления, а затем образцы отбросов. Для ясности полный файл: here. Статья о коде находится в Artima Developer.

ps: пожалуйста, не отвечайте с помощью C-стиля, отличные ... Пожалуйста, посмотрите на фактический код и объясните, как это имеет значение.

Код: Фактическая концепция проста, это тип обертки вокруг пользователя, который выбирает тип int, второй параметр шаблона. Это просто запрещает целый ряд операторов и конверсий.
Вопросы в комментариях:

template< unsigned int unique_index, typename word_t = unsigned long > 
class SafeBitConst 
{ 
    const word_t word; //< the actual data for the bitfield (only member, 
         // all the rest are overloaded operators) 

public: 
    // A. factory method to produce these, I'm wondering about the need of the 2 
    // casts in the the return as well as wondering if they are actually benificial 
    // or detrimental to compiler checks. 

    template < unsigned int i > 
    static SafeBitConst make_bit_const() 
    { 
     return SafeBitConst(i > 0 ? word_t(1) << (i - 1) : 0); 
    } 


    // B. all the shift operators with this cast 

    const SafeBitConst operator << (unsigned int s) const 
    { 
     return SafeBitConst(word << s); 
    } 
} 


// In a related but very similar type: 

explicit SafeBitField(word_t init) : word(init) {} 


// C. Casting your this pointer to your own type? 

SafeBitField operator &= (const SafeBitField & rhs) 
{ 
    word &= rhs.word; 
    return SafeBitField(*this); 
} 


// D. conversion to const bool? 
// I thought the constness of the receiving variable would be determined by 
// the declaration of that variable and not by the conversion operator 
// on MSVC this gives compiler warnings as well. 

operator const bool() const { return (0 != word); } 

имп: Я тоже сторонник пословицы «если это не сломано, не исправить», но в C++ я просто очень хотел, чтобы понять, что происходит, а не принимать код, который выглядит изворотливым.

+0

Куда вы проводите в вашем коде? – sylvanaar

+0

@ sylvanaar http://stackoverflow.com/questions/32168/c-cast-syntax-styles – nus

+1

Я не вижу приведения в стиле C, я вижу использование конструктора в стиле C++ - вы путаете 'typeName (val)' и '(typeName) val'? –

ответ

6

Если вы имеете в виду word_t(1) то:

  1. Это не "стиль C" слепок. В C вы напишете (word_t)1. Котируемый код не будет компилироваться как обычный C.
  2. Этот тип актера в операторе смены обычно позволяет избежать «подписания 1» в миксе и заставить все выражение подписаться. Это становится проблемой с правым сдвигом >> из-за расширения арифметических знаков.
  3. Учитывая (2) Я хотел бы заменить, что с подходящим буквальным как 1UL означает (unsigned long)1
+0

ok, у меня было упустил ясность этого конструктора. Если бы он не был явным, есть ли веские основания написать его явно? – nus

+0

1UL определенно сделает его более читаемым, но я reckon word_t, который является параметром шаблона, может быть меньше, чем unsigned long, и этот конструктор принимает word_t, так что может снова дать предупреждения ... – nus

+0

'return SafeBitField (* this);' это также происходит в этом коде, в то время как конструктор копирования не является явным. Это имеет смысл? – nus

1

А. Это не может быть неявно с помощью явного конструктора

explicit SafeBitConst(word_t init) : word(init) {} 

B. Некоторые компиляторы жалуются о неявном преобразовании типа возвращаемого значения. (Плюс та же проблема, что и в D).

C. Построение нового объекта, даже если возвращать ссылку на * этого будет достаточно.

D. Это была, вероятно, опечатка, которую компиляторы с радостью игнорируют.

+0

+1 для четкой экспозиции. Я думаю, было бы грубо добавить -1 поверх этого для вашего объяснения (B), поэтому я этого не делал. Cheers, –

+0

A. Правильно, это было бы неявно брошено в один и тот же тип конструктором Хорошо, я пропустил явное, когда я впервые задал свой вопрос, но разве это не просто для предотвращения ** неявного литья **? – nus

+0

btw, на D. мой компилятор не игнорирует его, он предупреждает об этом – nus

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