2017-02-22 49 views
2

我試圖使用str_const類靈感來自https://stackoverflow.com/a/15863826/2859099字典順序比較在編譯的時候兩個字符串在C++ 11

#include <cstddef> 
#include <stdexcept> 

class str_const 
{ 
public: 
    template<std::size_t N> 
    constexpr str_const(const char(&arr)[N]) noexcept : str{arr}, len{N - 1} 
    { 
    } 

    constexpr char operator[](std::size_t i) const 
    { 
     return i < len ? str[i] : throw std::out_of_range{""}; 
    } 

    constexpr std::size_t size() const noexcept { return len; } 

    constexpr operator const char*() const noexcept { return str; } 

    constexpr const char* c_str() const noexcept { return str; } 

private: 
    const char* const str; 
    const std::size_t len; 
}; 

考慮到C++ 11 constexpr功能的限制,如何實現以下逐一比較:

constexpr bool operator<(str_const lhs, str_const rhs) 
{ 
} 

回答

3
constexpr bool less_impl(const char* s1, std::size_t n1, const char* s2, std::size_t n2) 
{ 
    return n2 == 0 ? false : 
      n1 == 0 ? true : 
      *s1 == *s2 ? less_impl(s1 + 1, n1 - 1, s2 + 1, n2 - 1) : 
         *s1 < *s2; 
} 

constexpr bool operator<(str_const lhs, str_const rhs) 
{ 
    return less_impl(lhs.c_str(), lhs.size(), rhs.c_str(), rhs.size()); 
} 
2

通常你會寫一個循環。在這裏你需要用尾遞歸替換它。以下是我有:

#include <iostream> 
#include <type_traits> 
#include <cstddef> 

class str_const 
{ 
public: 
    template<std::size_t N> 
    constexpr str_const(const char(&arr)[N]) noexcept : str{arr}, len{N - 1} 
    { 
    } 

    constexpr char operator[](std::size_t i) const 
    { 
     return i < len ? str[i] : throw std::out_of_range{""}; 
    } 

    constexpr std::size_t size() const noexcept { return len; } 

    constexpr operator const char*() const noexcept { return str; } 

    constexpr const char* c_str() const noexcept { return str; } 

private: 
    const char* const str; 
    const std::size_t len; 
}; 

namespace detail { 
constexpr bool cmp(str_const lhs, str_const rhs, std::size_t idx) { 
return lhs.size()<=idx ? true : 
     rhs.size()<=idx ? false : 
     lhs[idx]<rhs[idx] ? true : 
     rhs[idx]<lhs[idx] ? false : 
     cmp(lhs,rhs,idx+1); 
} 
} 

constexpr bool operator<(str_const lhs, str_const rhs) { 
return detail::cmp(lhs,rhs,0); 
} 

int main() { 
std::cout << std::integral_constant< bool, str_const("def")<str_const("abc") >::value << std::endl; 
std::cout << std::integral_constant< bool, str_const("abc")<str_const("abc") >::value << std::endl; 
} 

注意,我換成你throw0因爲你扔不是一個常量表達式

+0

欣賞你的答案,但是我沒有看到那個throw語句有任何問題,因爲如果在constexpr上下文中調用它,它就會失敗。 –

+0

你是對的。 http://stackoverflow.com/questions/34280729/throw-in-constexpr-function – CygnusX1