rid*_*ous 6 c++ templates string-view c++20
我正在尝试编写一个简单的模板函数,它接受所有可能的 basic_string_view 但我总是收到编译器错误“找不到匹配的重载函数”。
我不知道原因;调用者显式转换为 string_view 是可行的,但我想避免这种情况;还是故意变硬?
是否有扣除准则可以防止这种情况发生?
有没有一种简单的方法可以将其实现为模板?
这里(以及godbolt)是我尝试过的:
#include <string_view>
#include <string>
template <typename CharT, typename Traits> void func(std::basic_string_view<CharT, Traits> value)
//template <typename CharT> void func(std::basic_string_view<CharT> value)
//void func(std::string_view value)
{}
int main() {
std::string s;
std::string_view sv(s);
char const cs[] = "";
std::string_view csv(cs);
std::wstring ws;
std::wstring_view wsv(ws);
wchar_t const wcs[] = L"";
std::wstring_view wcsv(wcs);
func(s);
func(sv);
func(cs);
func(csv);
func(ws);
func(wsv);
func(wcs);
func(wcsv);
}
Run Code Online (Sandbox Code Playgroud)
以下是 msvc、clang 和 gcc 显示的错误:
error C2672: 'func': no matching overloaded function foundx64 msvc v19.latest #3
error C2783: 'void func(T)': could not deduce template argument for '<unnamed-symbol>'x64 msvc v19.latest #3
error: no matching function for call to 'func'x86-64 clang (trunk) #1
error: no matching function for call to 'func(std::string&)'x86-64 gcc (trunk) #2
Run Code Online (Sandbox Code Playgroud)
编辑:
Yakks c++20 答案的混合演示,并添加了 Jonathans 原始字符指针支持。
basic_string_viewC++23 中有CTAD 的范围版本,因此在 C++23 中,可以使用该requires子句来约束basic_string_view{s}格式良好,并通过借用basic_string_view函数体中的CTAD 来推导其类型
#include <string_view>
template<typename StrLike>
requires requires (const StrLike& s)
{ std::basic_string_view{s}; }
void func(const StrLike& s) {
auto sv = std::basic_string_view{s};
// use sv
}
Run Code Online (Sandbox Code Playgroud)
也可以仅使用 C++20 通过检查传递给函数的参数是否是一个范围来完成此操作。basic_string_view然后可以使用采用迭代器的构造函数重载将该范围转换为 a 。
我还添加了一个可以处理 char 指针的重载,因为它们不是范围。
#include <string_view>
#include <string>
#include <type_traits>
#include <ranges>
template <typename CharT, typename Traits>
void func(std::basic_string_view<CharT, Traits> value) {
// ...
}
template<typename S> requires std::ranges::contiguous_range<S>
void func(const S& s) {
func(std::basic_string_view{std::ranges::begin(s), std::ranges::end(s)});
}
template<typename S> requires (!std::ranges::range<S> && requires (S s) { std::basic_string_view<std::remove_cvref_t<decltype(s[0])>>(s); })
void func(const S& s) {
func(std::basic_string_view<std::remove_cvref_t<decltype(s[0])>>(s));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
608 次 |
| 最近记录: |