c++ - 有什么方法可以编译时检查字符串用户定义的文字吗?

标签 c++ c++11 user-defined-literals

我正在写一个用户定义的 string将月份名称转换为数字的文字。这个文字的预期用法类似于

"Nov"_m

应该返回 11 .

目前我的代码看起来像

constexpr Duration operator ""_m(const char* str, size_t len)
{
    return convert_month_to_int(str, len);
}

哪里constexpr int convert_month_to_int(const char, size_t)是一个进行实际转换的函数(如果月份名称不正确,则返回 -1)。

问题是如果传递给这个文字的字符串没有指定任何月份,我想显示某种编译错误。我尝试使用 static_assert通过以下方式:

constexpr Duration operator ""_m(const char* str, size_t len)
{
    static_assert(convert_month_to_int(str, len) > 0, "Error");
    return convert_month_to_int(str, len);
}

但这不起作用,因为编译器不确定 convert_month_to_int(str, len)将是一个常量表达式。

有什么方法可以实现这种行为吗?

最佳答案

我以不同的方式解决了这个问题,既不使用枚举也不使用字符串字面量,并且即使未构造为 constexpr 也会检测到错误的月份名称:

#include "date.h"

int
main()
{
    using namespace date::literals;
    auto m1 = nov;                           // ok
    static_assert(unsigned{nov} == 11, "");  // ok
    auto m2 = not_a_month;
    test.cpp:86:15: error: use of undeclared identifier 'not_a_month'
        auto m2 = not_a_month;
                  ^
    1 error generated.
}

我使用的方法是定义一个 class type month这是 documented to be a literal class type .

然后我create constexpr instances of each month :

CONSTDATA date::month jan{1};
CONSTDATA date::month feb{2};
CONSTDATA date::month mar{3};
CONSTDATA date::month apr{4};
CONSTDATA date::month may{5};
CONSTDATA date::month jun{6};
CONSTDATA date::month jul{7};
CONSTDATA date::month aug{8};
CONSTDATA date::month sep{9};
CONSTDATA date::month oct{10};
CONSTDATA date::month nov{11};
CONSTDATA date::month dec{12};

(CONSTDATA 是一个宏,可以帮助 C++11 constexpr 支持 limp 的编译器)

我也对一周中的几天使用相同的技术。

以上都是使用 clang 和 -std=c++11 编译的。它也适用于 gcc。 constexpr 位在 VS 中损坏,但其他一切正常,包括在编译时检测错误的月份名称。

关于c++ - 有什么方法可以编译时检查字符串用户定义的文字吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38802483/

相关文章:

c++ - 将 union 与结构内的位字段结合使用的正确语法

c++ - 使用CMake构建Qt项目并从QMainWindow继承导致未引用的vtable错误

c++ - 如何做一个万物皆可引用的对象?

c++ - 这是在 C++11 中使用 unique_ptr 和移动语义实现 pimpl 的正确方法吗

c++ - 如何在头文件中使用用户定义的文字?

c++ - 不存在从 “cv::Mat”到 “IplImage”的合适的用户定义转换

C++ OSX 设置 w/Vs 代码还是?

c++ - Boost 记录器链接问题

c++ - VS2015 中的计时文字

c++ - 文字运算符的模板参数列表