编辑:
要处理浮点值以及整数类型场景,您可以使用用户定义的文字模板,例如:
#include <type_traits>
#include <utility>
#include <typeinfo>
#include <iostream>
template <class FloatingPointType, class... Cs>
constexpr FloatingPointType char_list_to_(Cs... cs) {
char arr[] = {cs...};
FloatingPointType lhs = 0;
bool contains_dot = false;
for (std::size_t i = 0; i < sizeof...(Cs) && !(contains_dot |= (arr[i] == '.')); i++) {
lhs *= 10;
lhs += arr[i] - '0';
}
FloatingPointType rhs = 0;
for (int i = sizeof...(Cs) - 1; i > 0 && arr[i] != '.'; i--) {
rhs /= 10;
rhs += arr[i] - '0';
}
rhs /= 10;
return (contains_dot)?lhs+rhs:lhs;
}
template <class FloatingPointType, char... Cs>
struct FloatingPointValue {
static constexpr FloatingPointType value = char_list_to_<FloatingPointType>(Cs...);
constexpr operator FloatingPointType() {
return value;
}
};
template <class FloatingPointType, char... Cs>
constexpr FloatingPointType FloatingPointValue<FloatingPointType, Cs...>::value;
template <char... Cs>
FloatingPointValue<double, Cs...> operator""_fv() {
return {};
}
template <typename U, typename V>
auto min(U,V) -> std::conditional_t<(U{}<V{}), U, V>
{ return {}; }
int main() {
auto w = min(3.14_fv, 2.71_fv);
std::cout << typeid(w).name() << " : " << w.value << std::endl;
}
输出:
18FloatingPointValueIdJLc50ELc46ELc55ELc49EEE : 2.71
c++filt -t 18FloatingPointValueIdJLc50ELc46ELc55ELc49EEE的输出:
FloatingPointValue<double, (char)50, (char)46, (char)55, (char)49>
[live demo]
但是,如果您希望将其应用于字符串文字,则目前缺乏对由 c++ 标准引起的功能的支持。但是,如果您能够接受不太便携的选项,那么 clang 和 gcc 支持 gnu 扩展:
#include <type_traits>
#include <utility>
#include <typeinfo>
#include <iostream>
template <class CharT, CharT... Cs>
struct Value {
static constexpr std::size_t size = sizeof...(Cs);
static constexpr CharT const value[sizeof...(Cs) + 1] = {Cs..., '\0'};
template <class RHS>
constexpr bool operator<(RHS) {
for (std::size_t i = 0; i < size && i < RHS::size; i++) {
if (value[i] != RHS::value[i]) {
return value[i] < RHS::value[i];
}
}
return size < RHS::size;
}
};
template <class CharT, CharT... Cs>
constexpr CharT const Value<CharT, Cs...>::value[sizeof...(Cs) + 1];
template <class CharT, CharT... Cs>
Value<CharT, Cs...> operator""_v() {
return {};
}
template <typename U, typename V>
auto min(U,V) -> std::conditional_t<(U{}<V{}), U, V>
{ return {}; }
int main() {
auto w = min("cde"_v, "abc"_v);
std::cout << typeid(w).name() << " : " << w.value << std::endl;
}
输出:
5ValueIcJLc97ELc98ELc99EEE : abc
c++filt -t 5ValueIcJLc97ELc98ELc99EEE 的输出:
Value<char, (char)97, (char)98, (char)99>
[live demo]