使用 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

谢谢!!

解决方法

好吧...鉴于 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 & 并调用主版本将 const 添加到 data

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
,

我发现了第二个实现:

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

测试用例:https://wandbox.org/permlink/ZOaO4NDI28yQHXy9

我认为比第一个简单,并且也适用于测试。看来这正是我要找的。​​p>