简体   繁体   English

C++ 中的函数模板特化,没有重载函数的实例

[英]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 ,比如stringconst 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM