是否可以根据某些事物是否为常量表达式来覆盖函数和/或模板?
基本上我想要做的是构建一个字符串类,如果传递一个静态字符串,或者指向一个的constexpr变量,它将只使用该指针,以后不会尝试删除它。
另一方面,如果类被交给缓冲区,则需要复制或采用它,然后在析构函数中删除它。
我认为最接近的可能是使用强大的typedef并要求程序员在该typedef下声明他/她的静态字符串。我想知道,如果那些比我聪明的人能想出一些不需要的东西。
答案 0 :(得分:1)
基本上我想要做的是构建一个字符串类,如果传递一个静态字符串,或者指向一个的constexpr变量,它将只使用该指针,以后不会尝试删除它。
我认为我们在这里面临XY-problem。知道某个表达式是否为constexpr
,不会告诉您它是否适合delete
。
我想说如果这个动作可能不合适,该函数不应该试图猜测是否删除。我相信调用者应该注意这一点,可能使用智能指针而不是来处理它。
换句话说,我会让函数接受左值引用,如果必须将指向的对象作为参数传递给函数,则让客户端取消引用指针。
我认为这种模式不仅仅适用于delete
:更一般地说,如果一段代码具有决定如何生成或计算某些值的责任 (例如,对象分配),然后责任正确执行某些相关或相应的操作(例如清理)应该属于同一段代码:
void foo(my_object& o)
{
// ...
}
my_object o;
foo(o);
// The argument has automatic storage, no need to delete
my_object* pO = new my_object();
foo(*pO);
// The argument was allocated through operator new, we must
// deallocate it through a corresponding call to delete
delete pO;
如果你真的希望在函数中进行发生的清理,你应该让客户端告诉函数如何执行它:
void foo(my_object& o, bool shouldDelete)
{
// ...
if (shouldDelete) { delete &o; }
}
my_object o;
foo(o, false); // "And don't try to deallocate this object please..."
my_object* pO = new my_object();
foo(*pO, true); // "Please, delete it for me" (we are delegating the
// responsibility of performing the material action,
// but not the one of knowing how!)
为了获得更大的灵活性,你甚至可以接受一个可调用的对象,这可以通过“委派执行物质操作的责任,而不是知道如何< / em>的“:
#include <functional>
void foo(my_object& o, std::function<void()> f = [] () { })
{
// ...
f();
}
int main()
{
my_object o;
foo(o); // "And don't do anything with this object when you're done..."
my_object* pO = new my_object();
foo(*pO, [=] () { delete pO; }); // "Please, do exactly this when done..."
}
如果您不需要在运行时确定可调用对象的类型,您甚至可以考虑将foo()
转换为函数模板。
最后,关于如何确定表达式是否为常量表达式的原始问题,这通常是不可能的,但是有一些技术可以帮助你解决问题 - 只是意识到他们的局限性。在这方面,您可能会发现this Q&A on StackOverflow相关。