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++和Boost以及C++ 11规范。但是我遇到了一个问题,我的大脑有问题。我在这里学习一个教程:教程说你可以用模板和lambda函数来概括递归函数的记忆。本教程还列出了与模板一起使用的递归阶乘和斐波那契函数。但是,指南仅使用斐波那契函数_C++_Templates_Boost_C++11_Static Variables - Fatal编程技术网

模板函数中的静态变量不';对于模板实例来说似乎不是唯一的 我试图学习使用C++和Boost以及C++ 11规范。但是我遇到了一个问题,我的大脑有问题。我在这里学习一个教程:教程说你可以用模板和lambda函数来概括递归函数的记忆。本教程还列出了与模板一起使用的递归阶乘和斐波那契函数。但是,指南仅使用斐波那契函数

模板函数中的静态变量不';对于模板实例来说似乎不是唯一的 我试图学习使用C++和Boost以及C++ 11规范。但是我遇到了一个问题,我的大脑有问题。我在这里学习一个教程:教程说你可以用模板和lambda函数来概括递归函数的记忆。本教程还列出了与模板一起使用的递归阶乘和斐波那契函数。但是,指南仅使用斐波那契函数,c++,templates,boost,c++11,static-variables,C++,Templates,Boost,C++11,Static Variables,我编写了一个测试程序,看看这一切是如何工作的,并在同一次运行中生成一个记忆斐波那契函数和阶乘函数。事实是,记忆化模板使用静态映射来存储缓存的值,并且似乎映射对于记忆化函数的每个实例都不是唯一的。这是预期的吗?我应该如何使映射对每个模板实例都是唯一的?在我开始使用C++11特性之前,我曾尝试创建一个模板类,该类接受一个boost函数来封装这个过程。静态映射在模板类中是唯一的吗 创建记忆功能的主要逻辑 // Template function to create memoized versions

我编写了一个测试程序,看看这一切是如何工作的,并在同一次运行中生成一个记忆斐波那契函数和阶乘函数。事实是,记忆化模板使用静态映射来存储缓存的值,并且似乎映射对于记忆化函数的每个实例都不是唯一的。这是预期的吗?我应该如何使映射对每个模板实例都是唯一的?在我开始使用C++11特性之前,我曾尝试创建一个模板类,该类接受一个boost函数来封装这个过程。静态映射在模板类中是唯一的吗

创建记忆功能的主要逻辑

// Template function to create memoized versions of recursive lambda functions
template<typename inType, typename outType>
std::function<outType(inType) > memoize(std::function<outType(inType) > foo) {
   return [foo](inType n) {
      static std::map<inType, outType> memo;

      outType ret;
      if (memo.count(n) > 0) {
         cout << "Cache Hit" << endl;
         ret = memo[n];
         return ret;
      }
      ret = foo(n);
      memo[n] = ret;
      return ret;
   };
}

// Recursive lambda fibonacci function
std::function<int(int) > fibonacci_r = [](int n) {
   if (n <= 1) {
      return n;
   } else {
      return fibonacci_r(n - 1) + fibonacci_r(n - 2);
   }
};

// Recursive lambda factorial function
std::function<int(int) > factorial_r = [](int n) {
   if (n == 0) {
      return 1;
   } else {
      return n * factorial_r(n - 1);
   }
};
int position = 7;
cout << "Fibonacci:" << endl;
cout << "Non Memo Fibonacci" << endl;
cout << position << "-> " << fibonacci_r(position) << endl;
cout << "Memo Fibonacci" << endl;
fibonacci_r = memoize(fibonacci_r);
cout << position << " -> " << fibonacci_r(position) << endl;

cout << endl;

cout << "Non Memo Factorial" << endl;
cout << position << " -> " << factorial_r(position) << endl;
cout << "Memo Factorial" << endl;
factorial_r = memoize(factorial_r);
cout << position << " -> " << factorial_r(position) << endl;
在输出的末尾,您可以看到Memo factorial有一个缓存命中。然而,我不认为它应该只有一次缓存命中。不管怎样,
7
不是13,13是fibonacci memo lambda下7的缓存值。

…似乎地图对于每个已记忆函数的实例都不是唯一的。这是预期的吗

您似乎忘记了实例wrt to
静态
变量基于类型,而不是参数值。两种情况下的类型
std::function
相同。显然,当只有一个实例时,您也只有一个静态
map


部分解决方案可以是:

template<typename inType, typename outType>
std::function<outType(inType) > memoize(std::function<outType(inType) > foo) {
   static int i = 0;
   ++i;
   return [foo](inType n) {
      static std::map<int, std::map<inType, outType>> memo;
      auto& m = memo[i];
      outType ret;
      if (m.count(n) > 0) {
         cout << "Cache Hit" << endl;
         ret = m[n];
         return ret;
      }
      ret = foo(n);
      m[n] = ret;
      return ret;
   };
}

然后
f1
f2
将不会共享相同的
map
。这也意味着如果你经常这样做,可能会占用大量内存。

好的,这很有道理。我做了一些额外的阅读,我了解了函数模板是如何实例化的,也就是说,在编译时,看看什么使用了这个模板函数,传递了什么类型,然后创建一个新函数来使用。然而,不是每次调用lambda都会创建一个新的映射吗?或者lambda的工作方式是否与编译时创建的lambda相同,并且每个共享其签名的lambda都将共享静态映射?@zero298 lambda的类型(闭包)只存在一次。每次调用都会提供此类型的另一个实例,但与函数一样,编码的lambda代码不会“复制”到每个实例中。代码本身只由编译器生成一次(当然是按照
inType
/
outType
)。啊,非常酷。我真的不打算把它用在任何事情上,只是作为一种学习工具。很高兴发现这些事情的一些方面,我不是很清楚。我将继续接受你的答案,因为它说明了为什么它不起作用,并且是一个很好的选择。
template<typename inType, typename outType>
std::function<outType(inType) > memoize(std::function<outType(inType) > foo) {
   static int i = 0;
   ++i;
   return [foo](inType n) {
      static std::map<int, std::map<inType, outType>> memo;
      auto& m = memo[i];
      outType ret;
      if (m.count(n) > 0) {
         cout << "Cache Hit" << endl;
         ret = m[n];
         return ret;
      }
      ret = foo(n);
      m[n] = ret;
      return ret;
   };
}
auto f1 = memoize(factorial_r);
auto f2 = memoize(factorial_r);