残念ながら、かなりクレイジーなCを使用した元のバージョンのライブラリからいくつかのマクロが残っています。特に、特定のタイプがそれらに渡されることを期待する一連のマクロがあります。 次の線に沿って何かを行うことは可能ですか:
static_assert(decltype(retval) == bool);
そしてどのように?賢い選択肢はありますか?
はい、マクロが悪いことは承知しています。 C++はCではないことを知っています。
@ ncleBens の提案を使用して、これが最もクリーンであることがわかりました。
#include <type_traits>
static_assert(std::is_same<decltype(retval), bool>::value, "retval must be bool");
式があるのでdecltype
が必要なようですが、型を確認したいのです。これを行うには、すでに十分な方法があります(C++ 03)。たとえば、ブール値をチェックするには
inline void mustBeBool(bool) { }
template<typename T> inline void mustBeBool(T t) { & (&t); } // Takes address of rvalue (&t)
// Use:
#define DifficultMacro(B) do { mustBeBool(B); foo(B); } while (false)
免責事項:これは悪い答えです。間違いなくはるかに優れた解決策があります。ほんの一例です:)
すでに実装されているはずですが、自分で実装するのは簡単です。
template <class T1, class T2> struct CheckSameType; //no definition
template <class T> struct CheckSameType<T,T>{}; //
template <class T1, class T2>
AssertHasType(T2)
{
CheckSameType<T1, T2> tmp; //will result in error if T1 is not T2
}
このように使用するには:
AssertHasType<bool>(retval);
代替(GManが提案):
template <class T1, class T2> struct SameType
{
enum{value = false};
}
template <class T> struct SameType<T,T>
{
enum{value = true};
};
のように使用する
static_assert(SameType<decltype(retval), bool>::value);
ほとんどのマクロは、inline
関数やテンプレートに置き換えることができます。適切な例として、過度に巧妙な引数サイズチェックのPosix isnan
マクロは、C++ 0xのテンプレートです。ああ、悪い例ですが、あなたはその考えを理解します。
そのルールの主な例外は、本質的に高水準の機能を実装するマクロです言語機能。たとえば、よりスマートな例外処理、共分散、またはパラメーター化された宣言のセット。
場合によっては、inline
関数またはテンプレートとして合理的に表現できないマクロを、よりスマートな種類の前処理、つまりコード生成に置き換えることができます。次に、必要なコードを生成するスクリプトがどこかにあります。たとえば、マクロとテンプレートを使用して純粋なC++でオプションクラスを実行することは可能ですが、それは厄介であり、より簡単で保守しやすい代替手段として、必要なクラスを生成するスクリプトを使用できますが、追加料金がかかりますステップを構築し、複数の言語を処理します。
乾杯&hth。、
const
およびvolatile
修飾子を気にし、タイプのconst
およびvolatile
の部分も、現在のタイプと正確に一致するようにしたい場合と比較して、実行してください @ Matt Joinerが言うように :
#include <type_traits>
static_assert(std::is_same<decltype(my_variable), uint64_t>::value,
"type must be `uint64_t`");
const
は気にせず、const
に関係なく、タイプが特定のタイプであることを確認したい場合は、代わりに次のようにします。ここではstd::remove_const<>::type
が必要であることに注意してください。
static_assert(std::is_same<std::remove_const<decltype(my_variable)>::type, uint64_t>::value,
"type must be `uint64_t` OR `const uint64_t`");
同じことがvolatile
にも当てはまります。タイプのvolatile
部分も気にしない場合は、std::remove_volatile<>::type
で無視できます。
static_assert(std::is_same<std::remove_volatile<decltype(my_variable)>::type, uint64_t>::value,
"type must be `uint64_t` OR `volatile uint64_t`");
const
OR volatile
を気にしない場合は、std::remove_cv<>::type
で両方を削除できます。
static_assert(std::is_same<std::remove_cv<decltype(my_variable)>::type, uint64_t>::value,
"type must be `uint64_t` OR `const uint64_t` OR `volatile uint64_t` OR `volatile const uint64_t`");
std::remove_cv<>
、std::remove_const<>
、std::remove_volatile<>