[英]Function template specialization in C++, no Instance of overloaded function
I'm learning about function template specialization in C++ and am tasked with writing a template function called plus
that returns the sum of it's two arguments which maybe of different types.我正在学习 C++ 中的函数模板专业化,并负责编写一个名为
plus
的模板函数,该函数返回它的两个参数的总和,这些参数可能是不同类型的。 One version that accepts by value and another by pointer.一种是按值接受,另一种是按指针接受。 As an added challenge, I'm asked to overload this function so that it concatenates two strings.
作为一个额外的挑战,我被要求重载这个函数,以便它连接两个字符串。
template <typename T1, typename T2> decltype(auto) plus(const T1& a, const T2& b) {
return a + b;
}
template <typename T1, typename T2> decltype(auto) plus(const T1* a, const T2* b) {
return *a + *b;
}
// concatenate two strings
template <>
std::string_view plus<std::string_view, std::string_view> (std::string_view a, std::string_view b) {
return std::string { a } + std::string{ b };
}
The problem is that I'm getting an error on the specialization overload of the function to concatenate two strings.问题是我在连接两个字符串的函数的专业化重载上遇到错误。 The reason I decided to choose
std::string_view
over std::string
is so that when calling the function with string literals ( const char*
) it wouldn't resolve to the second definition that accepts a const *
which I'm guessing would be resolved over std::string
.我决定选择
std::string_view
不是std::string
是,当使用字符串文字( const char*
)调用函数时,它不会解析为接受const *
的第二个定义,我猜这会通过std::string
解析。
So I can't really figure out what's going on.所以我真的无法弄清楚发生了什么。 Just a wild guess but maybe this has something to do with me having two different template functions called
plus
and it can't figure out which one I'm trying to specialize / overload?只是一个疯狂的猜测,但也许这与我有两个不同的模板函数有关,称为
plus
并且它无法弄清楚我正在尝试专门化/重载哪个?
UPDATE:更新:
The issue seems to be with template resolution.问题似乎与模板分辨率有关。 The definition that accepts
const T*
is always preferred for any string literals.接受
const T*
的定义始终是任何字符串文字的首选。 Just trying to find a fix.只是想找到解决办法。
This would be my suggestion:这将是我的建议:
template <typename T1, typename T2, typename T3> T3 plus(const T1& a, const T2& b) {
return a + b;
}
template <typename T1, typename T2, typename T3> T3 plus(const T1* a, const T2* b) {
return *a + *b;
}
template <typename T1, typename T2, typename T3> T3 plus(T1 a, T2 b) {
return a + b;
}
// concatenate two strings
template <>
std::string plus<std::string_view, std::string_view> (std::string_view a, std::string_view b) {
return std::string(a).append(b);
}
Since string views needs to refer to the content of another string you need to return a string since the newly created string_view would point to a temporary object.由于字符串视图需要引用另一个字符串的内容,因此您需要返回一个字符串,因为新创建的 string_view 将指向一个临时对象。
Also there is no way to concatenate 2 string_view's together since concatenating two strings together would require that string_view's are able to hold references to other string views (since they don't hold string content themselves).也没有办法将 2 个 string_view 连接在一起,因为将两个字符串连接在一起需要 string_view 能够保存对其他字符串视图的引用(因为它们本身不保存字符串内容)。
Furthermore, a third typename is required since this implementation would return another type (std::string) since you don't want to return a string_view of a temporary此外,需要第三个类型名,因为此实现将返回另一种类型 (std::string),因为您不想返回临时的 string_view
If you have access to C++20, then this could be done pretty easily with concepts.如果您可以访问 C++20,那么这可以通过概念轻松完成。
Anything that's convertible to string_view
, such as string
and const char*
, will be taken to this function:任何可以转换为
string_view
,比如string
和const char*
,都将被带到这个函数中:
template<typename T>
concept StringView = std::convertible_to<T, std::string_view>;
auto plus(StringView auto a, StringView auto b)
{
return std::string(a).append(b);
}
Similarly, you can define other concepts easily and just exlucde StringView
:同样,您可以轻松定义其他概念,只需排除
StringView
:
template<typename T>
concept Reference = std::is_reference_v<T> && !StringView<T>;
template<typename T>
concept Pointer = std::is_pointer_v<T> && !StringView<T>;
auto plus(const Reference auto a, const Reference auto b)
{
⋮
⋮
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.