首页 > 解决方案 > 在模板函数中将给定参数乘以 3 (C++)

问题描述

我正在尝试将给定的字符串“乘以” 3 - 它被传递给模板函数。

我收到错误消息:'initializing' cannot convert from 'T' to 'std::basic_string<char,std::char_traits,std::allocator<char'

template <typename T>
std::string bythree(T argument) {

  std::string message = "";
  
  if (typeid(argument) == typeid(std::string)) {
    std::string mul_str = argument + argument + argument;
    message = mul_str;
  }
}

当我使用以下逻辑时,我得到了这个std::string message = argument + argument + argument;

任何有关在此背后使用的逻辑的帮助将不胜感激。

标签: c++functiontemplates

解决方案


不管你使用什么类型,它仍然需要编译。因此,如果您传递一个int,它将尝试为该字符串分配一个 int 并失败。

要像您一样进行类型测试,有几种方法。您可以创建适用于所有类型的默认模板版本,以及具有您特定类型的非模板重载。如果适用,编译器将更喜欢非模板重载:

template <typename T>
std::string bythree(T argument) {
  return "not a string";
}

std::string bythree(std::string argument) {
  return argument + argument + argument;
}

您也可以改为专门化模板。您为特定类型的 T 提供“例外”:

template <typename T>
std::string bythree(T argument) {
  return "not a string";
}

template<>
std::string bythree<std::string>(std::string argument) {
  return argument + argument + argument;
}

您可以使用enable_ifwith type traits 来启用具有特定特征的 T 类型:

template <typename T, typename std::enable_if<!std::is_same<T, std::string>::value, int>::type = 0>
typename std::string bythree(T argument) {
  return "not a string";
}

template <typename T, typename std::enable_if<std::is_same<T, std::string>::value, int>::type = 0>
typename std::string bythree(T argument) {
  return argument + argument + argument;
}

在 C++17 中,您可以组合类型特征并if constexpr在函数内部进行类型测试,就像您尝试做的那样:

template <typename T>
std::string bythree(T argument) {
  if constexpr (std::is_same_v<T, std::string>) {
    return argument + argument + argument;
  } else {
    return "not a string";
  }
}

这在不适用的地方有效,因为如果条件不成立(在编译时评估),编译typeid(T) == typeid(std::string)器不会尝试编译块的内容。if constexpr


推荐阅读