如何用type_traits检测字符串文字? [英] How to detect a string literal with type_traits?

查看:89
本文介绍了如何用type_traits检测字符串文字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在不是字符串文字的地方可靠地static_assert?

How do I reliably static_assert on anything that isn't a string literal?

例如,在下面的代码中,我试图包装标准assert宏,但静态拒绝不是字符串字面量的消息的任何东西(因为除非是字符串字面量,在assert触发器时不会在运行时显示)。

For example, in the following code, I've attempted to wrap the standard assert macro but statically reject anything for the message that's not a string literal (since anything but a string literal will not be displayed at runtime when the assert triggers).

#include <cassert>
#include <string>
#include <type_traits>

#define my_assert(test, message)\
    static_assert(\
        (\
            !std::is_pointer<decltype(message)>::value &&\
            !std::is_array<decltype(message)>::value\
        ),\
        "literal string required"\
    );\
    assert((message, (test)));

int main() {
    my_assert(1 == 1, "one equals one");
    my_assert(1 == 2, "one equals two");

    {
        const char *msg = "one equals one";
        //my_assert(1 == 1, msg); // triggers static_assert
    }

    {
        const char msg[] = "one equals one";
        //my_assert(1 == 1, msg); // triggers static_assert
    }

    {
        const std::string msg = "one equals one";
        //my_assert(1 == 1, msg.c_str()); // triggers static_assert
    }

    {
        const int msg = 3;
        my_assert(1 == 1, msg); // should trigger static_assert
    }
}

测试通过type_traits标题提供的测试完成,而
大多是,这个代码按预期工作(用gcc 4.7.2测试)。但是,它不专门寻找字符串文字,因为它只是拒绝了一个程序员可以使用的常见事情。

As you can see, the testing is done via the tests provided by the type_traits header, and, mostly, this code works as intended (tested with gcc 4.7.2). However, it doesn't specifically look for string literals as much as it just rejects common things that a programmer might use in place.

我的解决方案可能够好对于上面的例子,但我想使用这个,或在其他情况下类似的技术。

The solution I have may be good enough for the example above, but I'd like to use this, or a similar technique in other situations as well.

所以问题是,如何可靠地使用type_traits

So the question is, how do I reliably use type_traits (or another standard mechanism) to static_assert on anything except a string literal?

推荐答案

这里是一个标准的机制最好我可以得到,它似乎拒绝任何我抛出它,但仍接受文字字符串:

Here is the best I could get, which appears to reject anything I throw at it, but still accepts literal strings:

#define my_assert(test, message)\
    static_assert(\
        (\
             std::is_convertible      <decltype(message), const char *>::value &&\
            !std::is_rvalue_reference <decltype(message)>::value &&\
            !std::is_pointer          <decltype(message)>::value &&\
            !std::is_array            <decltype(message)>::value &&\
            !std::is_class            <decltype(message)>::value\
        ),\
        "string literal required"\
    );\
    assert((message, (test)))

我很想知道这个实际上是否完全正确,和/或如果有一个更简单的方法做这个检测。

I'd be very interested to know if this actually is exhaustively correct, and/or if there is a simpler way to do this detection.

这篇关于如何用type_traits检测字符串文字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆