C++11新特性 - static_assert 的替代實現

名詞釋義

     如字面含義, 靜態(編譯時)斷言, 更多解釋見:

    不過, IDE未必支持這個C++11的新特性, 所以就會有一些替代的實現方法.

php

替代實現

    若編譯器不支持static_assert, 咱們應該怎麼自行實現該特性? 在Eigen中, 能夠找到答案:  利用模板特例化和編譯器編譯時 "undeclared identifier"的 報錯. 代碼以下:
namespace Eigen {

    namespace internal {

    template<bool condition>
    struct static_assertion {};

    template<>
    struct static_assertion<true>
    {
      enum {
        YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX,
        YOU_MIXED_VECTORS_OF_DIFFERENT_SIZES,
        YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES,
        THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE,
        THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE,
        THIS_METHOD_IS_ONLY_FOR_OBJECTS_OF_A_SPECIFIC_SIZE,
        YOU_MADE_A_PROGRAMMING_MISTAKE,
        EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT,
        EIGEN_INTERNAL_COMPILATION_ERROR_OR_YOU_MADE_A_PROGRAMMING_MISTAKE,
        YOU_CALLED_A_FIXED_SIZE_METHOD_ON_A_DYNAMIC_SIZE_MATRIX_OR_VECTOR,
        YOU_CALLED_A_DYNAMIC_SIZE_METHOD_ON_A_FIXED_SIZE_MATRIX_OR_VECTOR,
        UNALIGNED_LOAD_AND_STORE_OPERATIONS_UNIMPLEMENTED_ON_ALTIVEC,
        THIS_FUNCTION_IS_NOT_FOR_INTEGER_NUMERIC_TYPES,
        FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED,
        NUMERIC_TYPE_MUST_BE_REAL,
        COEFFICIENT_WRITE_ACCESS_TO_SELFADJOINT_NOT_SUPPORTED,
        WRITING_TO_TRIANGULAR_PART_WITH_UNIT_DIAGONAL_IS_NOT_SUPPORTED,
        THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE,
        INVALID_MATRIX_PRODUCT,
        INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS,
        INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION,
        YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY,
        THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES,
        THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES,
        INVALID_MATRIX_TEMPLATE_PARAMETERS,
        INVALID_MATRIXBASE_TEMPLATE_PARAMETERS,
        BOTH_MATRICES_MUST_HAVE_THE_SAME_STORAGE_ORDER,
        THIS_METHOD_IS_ONLY_FOR_DIAGONAL_MATRIX,
        THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE,
        THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_WITH_DIRECT_MEMORY_ACCESS_SUCH_AS_MAP_OR_PLAIN_MATRICES,
        YOU_ALREADY_SPECIFIED_THIS_STRIDE,
        INVALID_STORAGE_ORDER_FOR_THIS_VECTOR_EXPRESSION,
        THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD,
        PACKET_ACCESS_REQUIRES_TO_HAVE_INNER_STRIDE_FIXED_TO_1,
        THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS,
        YOU_CANNOT_MIX_ARRAYS_AND_MATRICES,
        YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION,
        THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY,
        YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT,
        THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS,
        THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL,
        THIS_METHOD_IS_ONLY_FOR_ARRAYS_NOT_MATRICES,
        YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED,
        YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED,
        THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE,
        THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH,
        OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG
      };
    };

    } // end namespace internal

    } // end namespace Eigen
#define EIGEN_STATIC_ASSERT(CONDITION,MSG) \
        {Eigen::internal::static_assertion<bool(CONDITION)>::MSG;}

SEE ALSO: Eigen\src\Core\util\StaticAssert.h ide

從上面的代碼能夠看出, 若是 EIGEN_STATIC_ASSERT 中的 CONDITION=false 時, 就會調用 Eigen::internal::static_assertion<false>::MSG , 再看看static_assertion定義, 它只特例化了static_assertion<true>, 而condition=false的模板參數則會調用默認的方法, 所以, 一旦 CONDITION=false , 編譯器就必然會找不到MSG的定義, 也就是咱們看到的"undeclared identifier". spa


參考資料

相關文章
相關標籤/搜索