c – 使用静态类变量而不分配它们
背景
所以今天早些时候我正在为std :: ofstream实现一个瘦包装器,它允许我轻松地写入.csv文件.我想覆盖<<运算符写入值后跟逗号,然后当新行的时间到来时,我会打印一个退格符,然后是一个新行.我决定将新行行为实现为模板特化,如下所示: // *this << value; => prints the value to the csv file // *this << CsvWriter::BREAK; => goes to the next line of the csv file // Example: // CsvWriter csv("test.csv",{"Col 1","Col 2","Col 3"}); // csv << "Value 1" << 2 << 3.25 << CsvWriter::BREAK; class CsvWriter { public: CsvWriter(const char *fname,std::vector<const char *> headers); CsvWriter() = delete; CsvWriter(const CsvWriter &) = delete; CsvWriter &operator=(const CsvWriter &) = delete; ~CsvWriter() = default; // Used for the template specialization below static struct LineBreak {} BREAK; template <typename T> CsvWriter &operator<<(T t); private: std::ofstream out_; bool first_ = true; // true when printing first element of line }; template <typename T> CsvWriter &CsvWriter::operator<<(T t) { if (!first_) { out_ << ','; } else { first_ = false; } out_ << t; return *this; } // This is the specialization for newlines. // If anything of type LineBreak is passed to this function,this executes. template <> CsvWriter &CsvWriter::operator<<(LineBreak) { out_ << std::endl; first_ = true; // Reset first for next line return *this; } // The constructor gives an example use of the template specialization CsvWriter::CsvWriter(const char *fname,std::vector<const char *> headers) : out_(fname) { for (const char *header : headers) { *this << header; // Prints each string in header } *this << BREAK; // Goes to the next line of the csv } 简要说明 这段代码完全按原样运行,并且在gcc中没有投诉.但是,我注意到我在技术上没有为BREAK值分配内存.所以为了检查它,我尝试打印& CsvWriter :: BREAK的值并遇到链接错误(这是有道理的,我要求的内容不在内存中).此外,如果我添加行CsvWriter :: LineBreak CsvWriter :: BREAK;在类定义之后,那么我可以打印& CsvWriter :: BREAK的值没问题(这也是有道理的,因为现在我已经给它了内存. 从这一点来说,我可以一起思考如果从未在任何编译单元中使用该值,链接器将永远不会查找该值并且永远不会抱怨它.但是如果我使用它(例如抓取地址),链接器将尝试链接名称,而不是找到任何东西. 题 虽然我发现这个结果对我正在尝试做的事情非常有用,但我很好奇,这在技术上是否符合C 11标准?或者这是完全有效的代码?如果没有,是否有更好的方法来使用类似的清晰简单的界面? 解决方法
这在技术上是一个不正确的计划.
可能发生的是编译器足够聪明,可以看到从不使用重载函数的参数值.因此,编译器不会发出代码以将未使用的BREAK值传递给重载的<<操作符.由于没有生成对符号的引用,链接器不会抱怨. 但是,如果您显式生成对象的引用,则链接将失败. C标准不要求编译器执行此优化,因此这是不正确的.因此,从技术上讲,C标准确实不允许这样做. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |