我想编写一个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中有特定于平台的方式吗?
答案 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);
您收到编译错误。