c++ 是否可以在编译时验证用户定义文本的输入

af7jpaap  于 2023-01-15  发布在  其他
关注(0)|答案(1)|浏览(128)

在下面的例子中,我希望在编译时被告知从long到int的转换改变了值,就像我不使用用户定义的文字一样。

#include <cassert>

constexpr int operator "" _asInt(unsigned long long i) {
    // How do I ensure that i fits in an int here?
    // assert(i < std::numeric_limits<int>::max()); // i is not constexpr
    return static_cast<int>(i);  
}

int main() {
  int a = 1_asInt;
  int b = 99999999999999999_asInt; // I'd like a warning or error here
  int c = 99999999999999999; // The compiler will warn me here that this isn't safe
}

我可以想出一些方法来得到一个运行时错误,但我希望有一些方法来使它成为一个编译时错误,因为据我所知,所有的元素都可以在编译时知道。

jhdbpxl9

jhdbpxl91#

将其设置为consteval

consteval int operator "" _asInt(unsigned long long i) {
    if (i > (unsigned long long) std::numeric_limits<int>::max()) {
        throw "nnn_asInt: too large";
    }
    return i;  
}

int main() {
  int a = 1_asInt;
  // int b = 99999999999999999_asInt;  // Doesn't compile
  int c = 99999999999999999;  // Warning
}

在C++17中,你可以使用一个文本运算符模板,但是它有点复杂:

template<char... C>
inline constexpr char str[sizeof...(C)] = { C... }; 

// You need to implement this
constexpr unsigned long long parse_ull(const char* s);

template<char... S>
constexpr int operator "" _asInt() {
    constexpr unsigned long long i = parse_ull(str<S..., 0>);
    static_assert(i <= std::numeric_limits<int>::max(), "nnn_asInt: too large");
    return int{i};
}

相关问题