覆盖常量表达式?

时间:2013-03-14 18:03:50

标签: c++ templates c++11 overloading constexpr

是否可以根据某些事物是否为常量表达式来覆盖函数和/或模板?

基本上我想要做的是构建一个字符串类,如果传递一个静态字符串,或者指向一个的constexpr变量,它将只使用该指针,以后不会尝试删除它。

另一方面,如果类被交给缓冲区,则需要复制或采用它,然后在析构函数中删除它。

我认为最接近的可能是使用强大的typedef并要求程序员在该typedef下声明他/她的静态字符串。我想知道,如果那些比我聪明的人能想出一些不需要的东西。

1 个答案:

答案 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相关。