Is constexpr useful for overload

后端 未结 3 2035
有刺的猬
有刺的猬 2021-01-21 23:52

Is there a way in c++ to get a different overload called based on the runtime/compile time constness of an input? My version(12) of MSVC can\'t do this using constexpr. Reading

3条回答
  •  Happy的楠姐
    2021-01-22 00:00

    To elaborate on my comment, you can try this to work around the limitation you're facing:

    Run It Online

    #include 
    using std::cout;
    using std::endl;
    
    template 
    constexpr int Flip4() {
        return ((n & 0xFF) << 24) | ((n & 0xFF00) << 8) | ((n & 0xFF0000) >> 8) | ((n & 0xFF000000) >> 24);
    }
    inline int Flip4(int n) {
        return _byteswap_ulong(n);
    }
    
    int main() {
        constexpr int a = Flip4<0xabcd>();  // calc at compile time
        int b = Flip4(0xabcd);  // calc at runtime
    
        static_assert(a == -844431360, "");
    
        cout << "a: " << a << endl;
        cout << "b: " << b << endl;
    }
    

    EDIT: Don't lose hope! User-defined literals are here to the rescue :)

    Run It Online

    #include 
    using std::cout;
    using std::endl;
    
    // wraps a single integer (unsigned long long) in order to use it in a user-defined literal
    // the type (unsigned long long) is a limitation of the standard: https://stackoverflow.com/a/16596909/865719
    struct IntegerWrapper
    {
        const unsigned long long value;
        constexpr explicit IntegerWrapper(unsigned long long val) : value{val} {}
    };
    // user-defined literal
    constexpr IntegerWrapper operator "" _iw (const unsigned long long value) 
    { 
        return IntegerWrapper{value};
    }
    
    constexpr int Flip4(IntegerWrapper&& n) {
        return ((n.value & 0xFF) << 24) | ((n.value & 0xFF00) << 8) | ((n.value & 0xFF0000) >> 8) | ((n.value & 0xFF000000) >> 24);
    }
    
    inline int Flip4(int n) {
        return _byteswap_ulong(n);
    }
    
    int main() {
    
        constexpr int a = Flip4(0xabcd_iw);  // calc at compile time
        const     int b = Flip4(0xabcd);     // calc at runtime
    
        static_assert(a == -844431360, "");
    
        cout << "a: " << a << endl;
        cout << "b: " << b << endl;
    }
    

提交回复
热议问题