首页 > 解决方案 > 使用 string_view 禁止临时参数的 trim_left 实现

问题描述

我想实现一个非复制数据 trim_left 函数,但不想让它接受临时参数以使返回的 string_view 有效(数据仍然存在)。我开始接受 string_view 作为参数,但我无法获得如何保证数据有效的方法。

所以我做了这个:

template<typename T>
std::string_view trim_left( const T& data, std::string_view trimChars )
{
    std::string_view sv{data};
    sv.remove_prefix( std::min(sv.find_first_not_of(trimChars), sv.size()));
    return sv;
}
template<typename T, std::enable_if_t< !std::is_same<std::decay_t<T>,std::string_view>::value , int > = 0>
std::string_view trim_left( const T&& data, std::string_view trimChars ) = delete; 

我对第二个删除模板的想法是禁用临时对象作为参数并保证返回的 string_view 是有效的。

我希望这是有效的:

auto sv1 = trim_left("ABCHello" , "ABC");
string data = "ABCHello";
auto sv2 = trim_left( data, "ABC");

但不是这个……

string fee( return "ABCHello"; );
auto sv3 = trim_left( fee(), "ABC");

这是正确的方法吗?是否可以通过在第一个模板上设置 enable_if 参数而不使用第二个模板来做到这一点?

测试实现:https ://wandbox.org/permlink/7q3cLGbGrX9b6q5S

谢谢!!

标签: c++templatesc++17temporary-objectsstring-view

解决方案


嗯......鉴于这trim_left()没有改变data,我想你可以写主trim_left()接收T const &

template <typename T>
std::string_view trim_left (T const & data, std::string_view trimChars)
 {
   std::string_view sv{data};
   sv.remove_prefix( std::min(sv.find_first_not_of(trimChars), sv.size()));
   return sv;
 } 

然后你可以添加一个辅助trim_left()接收一个T &并调用主版本添加constdata

template <typename T>
std::string_view trim_left (T & data, std::string_view tc)
 { return trim_left((T const &)data, tc); }

最后一个已删除trim_left()以供普遍参考

template <typename T>
std::string_view trim_left (T &&, std::string_view) = delete; 

现在你有

auto sv1 = trim_left("ABCHello" , "ABC"); // OK: main version (const &)

std::string data = "ABCHello";
auto sv2 = trim_left( data, "ABC"); // OK: auxiliary version (&)

// auto sv3 = trim_left( fee(), "ABC"); // compiler error: deleted version

推荐阅读