W wysiłku, aby moje teksty stałe więcej typesafe, Używam operatorów makro generowane przeciążony aby uniemożliwić porównując teksty stałe przed czymkolwiek ale identycznie wpisany ENUM:C++ niejawna konwersja do bool
#include <boost/static_assert.hpp>
#define MAKE_ENUM_OPERATOR_TYPESAFE(enumtype, op) \
template<typename T> \
inline bool operator op(enumtype lhs, T rhs) \
{ \
BOOST_STATIC_ASSERT(sizeof(T) == 0); \
return false; \
} \
\
template<> \
inline bool operator op(enumtype lhs, enumtype rhs) \
{ \
return static_cast<int>(lhs) op static_cast<int>(rhs); \
}
#define MAKE_ENUM_TYPESAFE(enumtype) \
MAKE_ENUM_OPERATOR_TYPESAFE(enumtype, ==) \
MAKE_ENUM_OPERATOR_TYPESAFE(enumtype, !=) \
MAKE_ENUM_OPERATOR_TYPESAFE(enumtype, >) \
MAKE_ENUM_OPERATOR_TYPESAFE(enumtype, <) \
MAKE_ENUM_OPERATOR_TYPESAFE(enumtype, >=) \
MAKE_ENUM_OPERATOR_TYPESAFE(enumtype, <=)
// Sample usage:
enum ColorType { NO_COLOR, RED, BLUE, GREEN };
MAKE_ENUM_TYPESAFE(ColorType)
to zazwyczaj ma pożądany efekt; porównania formularza color_variable == RED
pracy, podczas gdy porównania formularza color_variable == 1
generują błędy kompilacji dzięki Boost.StaticAssert. (Czy to przyzwoite podejście?)
Jednak mój kompilator (CodeGear C++ Builder) również próbuje wykorzystać te przeciążone operatory do implementacji niejawnych konwersji bool
. Na przykład if (color_variable) { ... }
jest tłumaczony na if (operator!=(color_variable, 0)) { ... }
i wyzwala BOOST_STATIC_ASSERT
i nie można go skompilować.
Jestem dość pewny, że jest to nieprawidłowe zachowanie ze strony mojego kompilatora (na przykład Comeau i GCC nie robię tego), ale zastanawiałem się, czy są jacyś prawnicy, którzy mogliby potwierdzić. Próbowałem przeglądać w projekcie standardu C++ 0x, ale wszystko, co mogłem znaleźć, to następująca instrukcja w sekcji 4.12:
Wartość zerowa, zerowa wartość wskaźnika lub wartość wskaźnika elementu zerowego jest przekształcana na wartość false; każda inna wartość jest konwertowana na wartość true.
bez szczegółów dotyczących sprawdzania "wartości zerowej".
Skoro próbujesz uczynić go bardziej bezpiecznym, czy nie ma sensu odrzucanie niejawnej konwersji na Bool? – Grizzly
Nie zdecydowałem, czy niedopuszczenie do konwersji na język bool było dobrą rzeczą. Istniejący kod, z którym mam do czynienia, porządkuje swoje wyliczenia tak, że wartość całkowita 0 jest fałszywa, a wszystko inne jest prawdziwe, więc konwersje bool są uzasadnione i prawdopodobnie poprawiają czytelność warunków. (Czytelność i styl programowania to prawdopodobnie osobne pytanie.) –
(A jeśli postanowię odrzucić niejawne konwersje do boolów, wolałbym nie robić tego w sposób, który działa tylko na jednym kompilatorze.) –