C ++ 11仅接受字符串文字的函数?

时间:2012-12-05 13:22:43

标签: c++ linux gcc c++11

我想编写一个C ++ 11函数,它只接受字符串文字作为参数:

 void f(const char* s) { static_assert(s is a string literal); ... }

那是:

 f("foo"); // OK

 char c = ...;
 f(&c); // ERROR: Doesn't compile

 string s = ...;
 f(s.c_str()); // ERROR: Doesn't compile

 etc

有没有实现这个?该函数的签名可以更改,就像添加宏或任何其他语言功能一样。

如果不可能,那么最接近的是什么? (用户定义的文字可以帮助吗?)

如果不是GCC 4.7 / Linux中有特定于平台的方式吗?

3 个答案:

答案 0 :(得分:13)

我认为你最接近的是这个

template<int N>
void f(const char (&str)[N]){
  ...
}

它将使用文字和数组进行编译,但不能使用指针进行编译。

答案 1 :(得分:3)

另一种方法可能是使GCC扩展在编译时检查您的特定函数是否仅使用文字字符串调用。

您可以使用MELT扩展GCC。 MELT是一种扩展GCC编译器的高级域特定语言,非常适合您想要的那种检查。

基本上,你会在GCC中添加一个新的传递和在MELT中传递的代码,它会找到每个gimple,这是对你的函数的调用,并检查参数确实是一个文字字符串。 melt-examples上的ex06示例应该会激励您。然后订阅gcc-melt@googlegroups.com并在那里询问您的MELT特定问题。

当然,这不是一个万无一失的方法:可以通过指针间接调用该函数,它可以例如有一个部分文字字符串,例如f("hello world I am here"+(i%4))在概念上是一个带有一些文字字符串的调用(例如在.rodata段中),但不在生成的代码中或在gimple中。

答案 2 :(得分:1)

我用这个:

// these are used to force constant, literal strings in sqfish binding names
// which allows to store/copy just the pointer without having to manage
// allocations and memory copies
struct _literalstring
{
    // these functions are just for easy usage... not needed
    // the struct can be empty
    bool equal(_literalstring const *other) { return !strcmp((const char *)this, (const char *)other); }
    bool equal(const char *other) { return !strcmp((const char *)this, other); }
    const char *str(void) { return (const char *)this; }
    bool empty(void) { return *(const char *)this == 0; }
};

typedef _literalstring *LITSTR;

constexpr LITSTR operator "" _LIT(const char *s, size_t) {
    return (LITSTR)s;
}

然后你只需要声明你的函数:

void myFunc(LITSTR str)
{
    printf("%s\n", str->str());
    printf("%s\n", (const char *)str);
    const char *aVar = str->str();
    const char *another = (const char *)str;
}

你这样称呼它:

myFunc("some text"_LIT);

如果您这样做:

myFunc("some text");
myFunc(aTextVariable);

您收到编译错误。