在编译时获取当前月份索引

rel*_*xxx 6 c++ visual-c++

我正在尝试在编译时将月份从__DATE__格式转换Mmm为数字.我需要它用于gcc和MS VC 2012.

我的尝试:

template <char C0, char C1, char C2>
struct month{};

template<> struct month < 'J', 'a', 'n'> { static const unsigned id = 1; };
template<> struct month < 'S', 'e', 'p'> { static const unsigned id = 9; };

static const char c0 = __DATE__[0];
static const char c1 = __DATE__[1];
static const char c2 = __DATE__[2];

static const unsigned currId = month<c0, c1, c2>::id;      //this gives error
static const unsigned currId2 = month<'S', 'e', 'p'>::id;  //this is fine
Run Code Online (Sandbox Code Playgroud)

在MS VC中给出

error C2970: 'month' : template parameter 'C0' : 'c0' : an expression involving objects with internal linkage cannot be used as a non-type argument

但是对于ideone工作正常.

有没有办法使这项工作跨平台/编译器?

编辑

我需要一个类似问题的compile-time constant答案并没有真正帮助.我需要例如减去两个日期(当前和代码中的某个日期),并在这两个日期之间的差异足够大时给出编译时错误.

Dav*_*ave 6

第一:你确定在编译时需要这个吗?如果运行时间可以接受,那很简单:http://www.keil.com/support/docs/1102.htm


但是,摆脱那些理智,让我们有一些编译时的乐趣!

你在这里使用模板,但你真的不需要.您可以使用大量的厄运表达:

static const char c0 = __DATE__[0];
static const char c1 = __DATE__[1];
static const char c2 = __DATE__[2];
static const unsigned int month = (
    c0 == 'J' // Jan Jun Jul
        ? (c1 == 'a' ? 1 : (c2 == 'n' ? 6 : 7))
    : c0 == 'F' ? 2
    : c0 == 'M' // Mar May
        ? (c2 == 'r' ? 3 : 5)
    : c0 == 'A' // Apr Aug
        ? (c1 == 'p' ? 4 : 8)
    : c0 == 'S' ? 9
    : c0 == 'O' ? 10
    : c0 == 'N' ? 11
    : 12
);
Run Code Online (Sandbox Code Playgroud)

免责声明:我刚刚写下了我的头脑.它现在有效,但谁知道,也许我错了三月.

事实上,如果你想获得更多乐趣*我们可以在一些角色上使用算术:

static const char c0 = __DATE__[0];
static const char c1 = __DATE__[1];
static const char c2 = __DATE__[2];
static const unsigned int month = (
    c0 == 'J' // Jan Jun Jul
        ? (c1 == 'a' ? 1 : (c2 == 'n' ? 6 : 7))
    : c0 == 'M' // Mar May
        ? (3 + (c2 == 'y') * 2)
    : c0 == 'A' // Apr Aug
        ? (4 + (c1 == 'u') * 4)
    : c0 == 'S' ? 9
    : c0 <= 'F' ? (12 - (c0 - 'D') * 5) // Feb, Dec
    : (11 + 'N' - c0) // Oct, Nov
);
Run Code Online (Sandbox Code Playgroud)

*:"有趣"我的意思是:被其他开发者讨厌

由于这些是const,因此您可以将它与模板一起使用.例如,假设我们的合同工作将于11月结束,我们希望确保一旦结束,我们将以高利率退回几天:

#include <iostream>
using namespace std;

static const unsigned int month = ...;

template <int n> class mm {
public:
    static int v;
};

template<> int mm<9>::v=3; // still employed
template<> int mm<10>::v=2; // let's not be too suspicious
template<> int mm<11>::v=1; // patience...
// no value for December - boom! we're in the money! Just in time for Christmas!

int main() {
    std::cout << mm<month>::v;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

最后,如果您不想乱丢全局范围,则应使用constexpr函数:

static constexpr int getMonth( void ) {
    const char c0 = __DATE__[0];
    const char c1 = __DATE__[1];
    const char c2 = __DATE__[2];
    return (
        c0 == 'J' // Jan Jun Jul
            ? (c1 == 'a' ? 1 : (c2 == 'n' ? 6 : 7))
        : c0 == 'F' ? 2
        : c0 == 'M' // Mar May
            ? (c2 == 'r' ? 3 : 5)
        : c0 == 'A' // Apr Aug
            ? (c1 == 'p' ? 4 : 8)
        : c0 == 'S' ? 9
        : c0 == 'O' ? 10
        : c0 == 'N' ? 11
        : 12
    );
}

...

std::cout << mm<getMonth()>::v;
Run Code Online (Sandbox Code Playgroud)