【问题标题】:C++11 constexpr string implementationC++11 constexpr 字符串实现
【发布时间】:2012-05-02 16:03:24
【问题描述】:

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

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。

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

【问题讨论】:

  • 我想你正在寻找来自akrzemi1.wordpress.com/2011/05/11/…的strwrap
  • String Literals const char (&amp;Var)[N] 是 constexpr 字符串类型。
  • 当人们在获得批准之前就开始使用 static if 等功能时,您一定会喜欢上它们!
  • @David:如果人们还没有尝试使用某个功能,我就不会批准它。此类功能的技术术语是“无用”;-)
  • @SteveJessop:嗯,提案和语言有很多粗糙的角落,首先是它如何与两阶段查找交互(这在 D 中不是问题)。再说一次,有一些被接受的提议没有被使用(考虑右值引用),但显然是一种改进。 有一个实现和用例和它在 SO 中使用之间有很大的区别。另请注意,这不是批评,而是对提案的赞扬:人们在听到这个概念后就开始使用它已经足够了!

标签: c++ c++11 constexpr


【解决方案1】:

这不仅仅是破坏的问题。

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

因此,永远不可能得到constexpr string。

【讨论】:

  • 它甚至不能在非 constexpr 构造函数中?似乎应该可以同时拥有给定类型的 constexpr 和 non-constexpr 构造函数,就像可以拥有 const 和非 const 方法一样。
  • 您完全可以创建一个constexpr 字符串类型,它只是无法处理非constexpr 字符串。只需制作转换函数即可。
  • 在我看来,constexpr 是一种模糊编译时间和运行时间计算之间界限的方法。原始类型允许这样做,并且似乎应该可以做一些事情来允许类中的指针指向文字或动态分配的内存。函数式语言已经抽象了编译时间/运行时间边界已经有一段时间了。 @Mooing Duck:转换函数似乎打破了抽象
  • @RobertMason:堆高度依赖于运行时(并且是有状态的)并且不能在编译时执行。时期。您能做的最好的事情就是在启动时在运行时进行。
  • "你完全可以创建一个 constexpr 字符串类型,它只是无法处理非 constexpr 字符串。"。这根本不是真的。非拥有的运行时字符串类是完全可行的。又名'stringref.
【解决方案2】:

在一定程度上是有可能的,见the code example in this page。您可以创建 constexpr conststr 对象并对其调用一些操作,但不能将它们用作非类型模板参数。

【讨论】:

    猜你喜欢
    • 2014-12-28
    • 2018-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-21
    • 1970-01-01
    相关资源
    最近更新 更多