7

有没有办法实现字符串在编译时和运行时都可以工作?

AFAIK 对于要构造的 constexpr 类,它需要有一个微不足道的析构函数。然而,当我们处理字符串时,这被证明是困难的。如果字符串不是 constexpr,那么它需要释放内存。但是,如果它是 constexpr,那么它是静态分配的,不应该被删除,从而允许一个微不足道的析构函数。

但是,不可能说“嘿,编译器!如果我是 constexpr,你就不需要破坏我!” 或者是吗?

这将类似于以下内容:

class string {
private:
    char * str;
public:
    template<std::size_t l>
    constexpr string(const char (&s)[l]) : str(&(s[0])) {}
    string(const char * s) { str = strdup(s); }
    static if (object_is_constexpr) {
        ~string() = default;
    }
    else {
        ~string() { free(str); }
    }
};

我能做到的最接近的是有两种不同的类型,string 和 constexpr_string,一个用户定义的文字 _string 返回 constexpr_string,以及一个用户定义的从 constexpr_string 到 string 的隐式转换。

虽然这不是很好,但可以const auto s = "asdf"_string;正常工作但const string s = "asdf"_string;不能。此外,指向 constexpr_string 的引用/指针不会转换。无论哪种方式的继承都会导致不直观的“陷阱”,并且不能解决第一个问题。

这似乎应该是可能的,只要编译器相信程序员不需要破坏 constexpr。

如果我有误解,请告诉我。

4

2 回答 2

11

这不仅仅是破坏的问题。

一个constexpr操作应该只调用其他constexpr操作newmalloc等等...不是 constexpr。请注意,这是一个静态检查的属性,不依赖于运行时参数,因此对此类函数的调用必须完全不存在,而不仅仅是隐藏在(假定)未采用的分支中。

因此,永远不可能获得constexpr string.

于 2012-05-02T16:18:58.167 回答
0

在某种程度上,有可能看到这个页面中的代码示例。您可以创建 constexprconststr对象并对它们调用一些操作,但不能将它们用作非类型模板参数。

于 2015-10-15T08:35:55.997 回答