如何声明对字符串无助的政策类,与其他政策具有一致的签名,并在编译时进行评估
我正在整理一组策略类,这些策略类可操作许多操作到字符串。我希望这些策略可以交换,但是“无所事事”的政策也很有问题,因为:
- 我看不到如何避免使用移动语义复制,同时与姐妹策略保持相同的(非移动)
- 接口编译器应该知道,可以在编译时对策略的调用进行内衬和评估,但是它不接受
constexpr
,因为返回类型是字符串。
#include <string>
#include<regex>
#include<cassert>
///
/// @brief Do not change anything
///
struct identity
{
static std::string edit(std::string&& s) // can not use constexpr: return type not a literal
{
return std::move(s);
}
};
///
/// @brief Template class.
///
template<unsigned int N>
struct remove_comments_of_depth
{};
///
/// @brief Do not remove anything
///
template<> struct remove_comments_of_depth<0> : identity
{};
///
/// @brief Remove all comments substrings contained between square brackets
///
/// @note Assumes that text is well formatted so there are no such things like [[]] or unclosed bracket
///
template<> struct remove_comments_of_depth<1>
{
static std::string edit(const std::string& s)
{
return std::regex_replace(s, std::regex(R"(\[[^()]*\])"), "");
}
};
int main(int argc, char *argv[])
{
std::string s = "my_string[this is a comment]";
auto copy = s;
assert(remove_comments_of_depth<1>::edit(s) == "my_string");
assert(remove_comments_of_depth<0>::edit(std::move(copy)) == s); // <<< how to avoid this call to std::move
}
在这种情况下,“标准”的方法是什么?
I am putting together a set of policy classes that operate a number of operations to a string. I would like these policies to be exchangeable, but the "do nothing" policy is problematic too me, as:
- I don't see how to avoid copy using move semantic while maintaining the same (non-move) interface with the sister policies
- The compiler should know that the call to the policy can be inlined and evaluated at compile time, but it does not accept
constexpr
because the return type is a string.
#include <string>
#include<regex>
#include<cassert>
///
/// @brief Do not change anything
///
struct identity
{
static std::string edit(std::string&& s) // can not use constexpr: return type not a literal
{
return std::move(s);
}
};
///
/// @brief Template class.
///
template<unsigned int N>
struct remove_comments_of_depth
{};
///
/// @brief Do not remove anything
///
template<> struct remove_comments_of_depth<0> : identity
{};
///
/// @brief Remove all comments substrings contained between square brackets
///
/// @note Assumes that text is well formatted so there are no such things like [[]] or unclosed bracket
///
template<> struct remove_comments_of_depth<1>
{
static std::string edit(const std::string& s)
{
return std::regex_replace(s, std::regex(R"(\[[^()]*\])"), "");
}
};
int main(int argc, char *argv[])
{
std::string s = "my_string[this is a comment]";
auto copy = s;
assert(remove_comments_of_depth<1>::edit(s) == "my_string");
assert(remove_comments_of_depth<0>::edit(std::move(copy)) == s); // <<< how to avoid this call to std::move
}
What is the "standard" way to go in this kind of situation?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您想要的是减少不必要的副本,并且在调用
编辑
时不要使用std ::移动
。为什么不返回const引用?请参阅在线演示
关于您的第二个问题,因为C ++ 20,
std :: string string
可以是字面类型。在C ++ 20中完全可以,请参见 demo 。
但是,由于您的变量
s
不能为constexpr
(它在运行时创建),因此这里没有很大的帮助。What you want here is reduce unnecessary copy and don't use
std::move
when callingedit
. Why not just return a const reference?See Online Demo
As to your second question, since C++20,
std::string
can be a literal type.It's totally fine in C++20, see Demo.
But since your variable
s
can't beconstexpr
(it's created at run-time), there's no big help here.