c++ 获取可变变量函数中具有特定类型的第一个变量

wmvff8tz  于 2023-02-20  发布在  其他
关注(0)|答案(2)|浏览(177)

这是我的第二篇文章,我在发表之前尽可能多地寻找信息(包括chatgpt的新功能)来了解变参数函数的工作。第一次尝试运行良好,我检查了给定的参数列表是否包括一个特定类型的参数。

template<typename T, typename Arg>
auto hasType(Arg arg) -> bool {
  return std::is_same<T, decltype(arg)>::value;
}

template <typename T, typename... Args>
auto hasType(Args... args) {
  return (hasType<T>(args) || ...);
}

// call like
std::string thisIsATest = "this is a test";
hasType<float>(thisIsATest, "Hello, world!", 5.67, 452);

现在,下一步是获取第一个参数的值,我创建了两个新的变量方法:

// The fall back if there is none of the specific type i search
template<typename T>
auto getFirst() -> T {
  throw someCustomException("Argument list not including the specific type.");
}

template<typename T, typename Arg, typename... Args>
auto getFirst(Arg arg, Args... args) -> T {
  // test if arg is not the same type and call recursive the function with
  // next argument
  if (!(std::is_same<T, decltype(arg)>::value)) {
    return getFirst<T>(args...);
  }
  // the arg should now match the condition to match type with T
  return arg;
  //-----^--- Multiple Errors like : could not convert ‘arg’ from ‘int’ to ‘std::__cxx11::basic_string<char>’ Or error: could not convert ‘arg’ from ‘double’ to ‘std::__cxx11::basic_string<char>’ 
}

我们的想法是这样调用getFirst:

std::string thisIsATest = "This is a test";
std::string thisIsAnOtherString = "This is an other string";
int intValue = 5;
double doubleValue = 28.563;
auto result = getFirst<std::string>(5, 1.2567, intValue, true, thisIsATest, doubleValue, false, 945.621, thisIsAnOtherString);
// result = thisIsATest

我尝试了一些改变,比如:

  • 将getFirst的返回类型由T改为Arg(调用"return getFirst(args ...)"时其他错误;")
  • 将第一个参数从值更改为引用=〉与示例中提供的错误相同
  • 尝试将arg转换为类型T,但未找到工作可能性

现在我有点陷入了这个问题,在哪里做必要的修改来达到这个功能,或者这是否是可以达到的。也许有人可以在这里帮助我。
谢谢。

rqqzpn5f

rqqzpn5f1#

请使用另一个重载,而不要使用std::is_same

template<typename T>
T getFirst() // recursion base case
{
    throw whatever();
}

template<typename T, typename... Args>
T getFirst(T& arg, Args... args) // matching case
{
    return arg;
}

template<typename T, typename Arg, typename... Args>
T getFirst(Arg arg, Args... args) // continuing the search case
{
    return getFirst(args);
}
92vpleto

92vpleto2#

auto返回类型推导要求从不同的return语句推导出的类型匹配。您的语句不需要。您使用if constexpr来丢弃false分支,那么推导返回类型就没有问题了:

template<typename T, typename Arg, typename... Args>
auto getFirst(Arg arg, Args... args) -> T {
  if constexpr  (!(std::is_same<T, decltype(arg)>::value)) {
    return getFirst<T>(args...);
  } else {
    return arg;
  }
}

Complete Example

相关问题