是否可以创建一个构造函数(或函数签名,就此而言),仅接受字符串文字,但不接受例如char const *
?
是否可以有两个重载可以区分字符串字面量和char const *
?
C++ 0x 会允许使用自定义后缀 - 但我正在寻找“早期”解决方案。
基本原理:避免在以字符串文字形式给出时不会被修改的字符串堆拷贝。
这些字符串直接发送到 API,需要 const char *
,无需任何处理。大多数调用确实使用不需要额外处理的文字,仅在少数情况下它们是构造的。我正在寻找一种保留 native 调用行为的可能性。
注意: - 因为它出现在答案中:有问题的代码根本不使用 std::string
,但一个很好的例子是:
class foo
{
std::string m_str;
char const * m_cstr;
public:
foo(<string literal> s) : m_cstr(p) {}
foo(char const * s) : m_str(s) { m_cstr = s.c_str(); }
foo(std::string const & s) : m_str(s) { m_cstr = s.c_str(); }
operator char const *() const { return m_cstr; }
}
结果:
(1) 做不到。
(2) 我意识到我什至不是在寻找文字,而是在寻找编译时常数(即“任何不需要复制的东西”)。
我可能会改用以下模式:
const literal str_Ophelia = "Ophelia";
void Foo()
{
Hamlet(str_Ophelia, ...); // can receive literal or string or const char *
}
用一个简单的
struct literal
{
char const * data;
literal(char const * p) : data(p) {}
operator const char *() const { return data; }
};
这并不能阻止任何人滥用它(我应该找到一个更好的名字......),但它允许进行所需的优化,但默认情况下仍然是安全的。
最佳答案
基于 sbi idea 的工作解决方案:
struct char_wrapper
{
char_wrapper(const char* val) : val(val) {};
const char* val;
};
class MyClass {
public:
template< std::size_t N >
explicit MyClass(const char (&str)[N])
{
cout << "LITERAL" << endl;
}
template< std::size_t N >
explicit MyClass(char (&str)[N])
{
cout << "pointer" << endl;
}
MyClass(char_wrapper m)
{
cout << "pointer" << endl;
}
};
int main()
{
MyClass z("TEST1"); // LITERAL
const char* b = "fff";
MyClass a(b); // pointer
char tmp[256];
strcpy(tmp, "hello");
MyClass c(tmp); // pointer
}
关于C++:仅接受字符串文字的构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2041355/