我想写一个C ++ 11函数,只接受string文字作为参数:
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
有没有实施这个? 该function的签名可以随时更改,如同添加macros或任何其他语言function一样。
如果这是不可能的,最接近的近似值是什么? (用户定义的文字可以帮助吗?)
如果不是在GCC 4.7 / Linux中有特定平台的方式吗?
我想最接近你会得到的是这个
template<int N> void f(const char (&str)[N]){ ... }
它将用文字和数组编译而不是指针。
另一种方法是在编译时检查一下GCC扩展,以确定你的特定函数只是用一个字符串来调用。
你可以使用MELT来扩展GCC。 MELT是扩展GCC编译器的高级别领域专用语言,非常适合您想要的检查。
基本上,你可以在GCC中添加一个新的代码,并在MELT中传递代码,这个代码会找到每一个调用你的函数的疙瘩,并检查这个参数确实是一个文本字符串。 关于融化示例的ex06
例子应该会激励你。 然后订阅gcc-melt@googlegroups.com,并在那里询问您的MELT特定问题。
当然,这不是一个万无一失的方法:函数可以间接地通过指针来调用,它可以有一个部分的文字字符串,例如f("hello world I am here"+(i%4))
在概念上是一个调用与一些文字字符串(例如在.rodata
段),但不是在生成的代码,也不是在疙瘩。
我使用这个:
// 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);
你得到一个编译器错误。