函数模板专用化C++,没有重载函数的实例



我正在学习C++函数模板专用化,并负责编写一个名为plus的模板函数,该函数返回其两个参数的总和,这两个参数可能属于不同类型的参数。一个版本按值接受,另一个版本接受指针。作为额外的挑战,我被要求重载此函数,以便它连接两个字符串。

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 };
}

问题是我在连接两个字符串的函数的专用化重载上收到错误。我决定选择std::string_view而不是std::string的原因是,当使用字符串文字(const char*)调用函数时,它不会解析为接受const *的第二个定义,我猜这将在std::string上解决。

所以我真的无法弄清楚发生了什么。只是一个疯狂的猜测,但也许这与我有两个不同的模板函数plus有关,它无法弄清楚我试图专门化/重载哪一个?

更新:

问题似乎与模板分辨率有关。接受const T*的定义始终是任何字符串文本的首选。只是试图找到解决方法。

这是我的建议:

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);
}

由于字符串视图需要引用另一个字符串的内容,因此您需要返回一个字符串,因为新创建的string_view将指向一个临时对象。

此外,没有办法将 2 个string_view连接在一起,因为将两个字符串连接在一起需要string_view能够保存对其他字符串视图的引用(因为它们本身不保存字符串内容)。

此外,需要第三个类型名,因为此实现将返回另一种类型(std::string),因为您不想返回临时的string_view

如果您可以访问 C++20,那么这可以通过概念轻松完成。

任何可转换为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);
}

同样,您可以轻松定义其他概念,只需解释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)
{
⋮
⋮

最新更新