代码之家  ›  专栏  ›  技术社区  ›  Eric

为什么我可以覆盖-(否定)和的运算符!(不是)但不是(按位不是)?

  •  1
  • Eric  · 技术社区  · 7 年前

    ! - ~ 接线员?

    #include <type_traits>
    #include <cstdint>
    #include <typeinfo>
    #include <cstdio>
    
    template <typename T, T v>
    struct integral_constant
        : std::integral_constant<T, v>
    {
    };
    
    #define DECL_UNARY_OP(op) \
        template <typename T, T t> \
        constexpr integral_constant<decltype(op t), (op t)> \
        operator op(integral_constant<T, t>) \
        { return {}; } \
    
    
    DECL_UNARY_OP(~);
    DECL_UNARY_OP(-);
    DECL_UNARY_OP(!);
    
    int main() {
        constexpr auto x = integral_constant<uint8_t, 1>{};
        constexpr auto y = integral_constant<uint8_t, 10>{};
        constexpr auto z = integral_constant<uint8_t, 100>{};
        puts(typeid(-x).name());  // integral_constant<...>
        puts(typeid(~y).name());  // int!
        puts(typeid(!z).name());  // integral_constant<...>
    }
    

    the following on godbolt integral_constant 类型。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Eric    7 年前

    通过消除 std::integral_constant

    #include <cstdint>
    #include <typeinfo>
    #include <cstdio>
    
    template <typename T, T v>
    struct integral_constant { };
    
    template <typename T, T t>
    constexpr integral_constant<decltype(~t), (~t)>
    operator ~(integral_constant<T, t>) { return {}; }
    
    
    int main() {
        constexpr auto y = integral_constant<uint8_t, 10>{};
        puts(typeid(~y).name());
    }
    

    现在呢 fails to compile with

    <source>: In function 'int main()':
    <source>:17:17: error: no match for 'operator~' (operand type is 'const integral_constant<unsigned char, 10u>')
         puts(typeid(~y).name());
                     ^
    <source>:17:17: note: candidate is:
    <source>:11:1: note: template<class T, T t> constexpr integral_constant<decltype (~ t), (~ t)> operator~(integral_constant<T, t>)
     operator ~(integral_constant<T, t>)
     ^
    <source>:11:1: note:   template argument deduction/substitution failed:
    <source>: In substitution of 'template<class T, T t> constexpr integral_constant<decltype (~ t), (~ t)> operator~(integral_constant<T, t>) [with T = unsigned char; T t = 10u]':
    <source>:17:18:   required from here
    <source>:11:1: error: 't' was not declared in this scope
    Compiler returned: 1
    

    这似乎可以通过添加额外的括号来解决,

    -integral_constant<decltype(~t), (~t)>
    +integral_constant<decltype((~t)), (~t)>
    
    推荐文章