Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用模板参数时模板参数推断失败_C++_Templates_Type Deduction - Fatal编程技术网

C++ 使用模板参数时模板参数推断失败

C++ 使用模板参数时模板参数推断失败,c++,templates,type-deduction,C++,Templates,Type Deduction,我想创建一个简单的辅助算法,用几何级数填充容器,比如std::vector,第一项是a,第n项是a*powr,n-1,其中r是给定的比率;我创建了以下代码: #include<vector> #include<algorithm> #include<iostream> template<template <typename> class Container, typename T> void progression(Container

我想创建一个简单的辅助算法,用几何级数填充容器,比如std::vector,第一项是a,第n项是a*powr,n-1,其中r是给定的比率;我创建了以下代码:

#include<vector>
#include<algorithm>
#include<iostream>

template<template <typename> class Container, typename T>
void progression(Container<T>& container, T a, T ratio, size_t N) {
  if(N > 0) {    
    T factor = T(1);  
    for(size_t k=0; k<N; k++) {
      container.push_back(a * factor);
      factor *= ratio;
    }
  }
}

int main() {
  std::vector<double> r;
  progression(r, 10.0, 0.8, static_cast<size_t>(10));

  for(auto item : r) {
    std::cout<<item<<std::endl;
  }

  return 0;
}
输出:

10
8
6.4
5.12
4.096
3.2768
2.62144
2.09715
1.67772
1.34218

失败的原因是,您说中间的两个参数是同一类型的,而实际上它们不是。例如,中间是一个float,而另一个是int。基本上你说a和ratio是相同的类型,但在调用中它们是不同的类型。容器通常有很多模板参数。幸运的是,变量模板中有一个特殊的子句,允许对任何具体数量的参数使用包:

template <template <typename...> class Container, typename ...Args>
void foo(Container<Args...> const & c)
{
    // ...
}
special子句的作用是,即使容器是非可变模板,它也可以工作。

第一个问题是,您忘记了std::vector是一个类模板,它接受两个模板参数:元素类型和分配器,而不是一个。使用模板参数时,第二个模板参数具有默认值这一事实与此无关:

template<template <typename, typename> class Container, typename T, typename A>
//                           ^^^^^^^^                               ^^^^^^^^^^
void progression(Container<T, A>& container, T a, T ratio, size_t N) {
//                         ^^^^
// ...
}
然后,您可能想做的是表示编译时约束,可能是通过一个静态_断言并基于一个自定义类型特征,即C必须是一个标准容器的实例

或者,您可以使用可变模板,但这仍然不会阻止您传递任何其他类型模板的实例,即使是非容器模板

第二个问题是调用模板的方式:

progression(r, 10, 0.8, 10);
这里,第二个参数的类型是int,而容器元素的类型是double。这将在执行类型推断时混淆编译器。或者这样称呼它:

progression(r, 10.0, 0.8, 10);

或者允许编译器为第二个参数推断出一种不同的类型(可能是因为约束它可以转换为元素类型)。

我想你的意思是中间的参数是双精度的,前面的参数也应该是双精度的。看看我的编辑,这不是问题所在。即使我通过两个双精度运算并将整数转换为大小,问题仍然存在。@aaronman-事实上这是一个问题-在我删除第一个错误后,您描述的错误确实出现了。@Arrieta不幸的是,我无法回答第二个问题。您能解释一下模板的语法吗?这不是可变模板。我从未想过要这样做。很好。谢谢你-最终的实现使用了你建议的语法。我实际上有一个改进版的答案,但是我的网络连接中断了,我无法从手机上编辑。这真是一团糟。
template<template <typename, typename> class Container, typename T, typename A>
//                           ^^^^^^^^                               ^^^^^^^^^^
void progression(Container<T, A>& container, T a, T ratio, size_t N) {
//                         ^^^^
// ...
}
template<typename C, typename T, typename A>
//       ^^^^^^^^^
void progression(C& container, T a, T ratio, size_t N) {
//               ^^
// ...
}
progression(r, 10, 0.8, 10);
progression(r, 10.0, 0.8, 10);