我尝试使用https://stackoverflow.com/a/15863826/2859099启发的str_const
课程
#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)
{
}
答案 0 :(得分: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());
}
答案 1 :(得分: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;
}
注意,我已将。throw
替换为0
,因为您投掷的内容不是常量