【发布时间】:2015-10-11 18:52:52
【问题描述】:
因为F 类型不符合特化,下面代码中被注释掉的行无法编译。谁能解释一下原因?
#include <memory>
#include <functional>
#include <map>
#include <tuple>
template <typename R, typename T, typename... Args>
std::function<R(Args...)> memoizeMemberFunction (R T::*f(Args...), const T* t) {
auto cache = std::make_shared<std::map<std::tuple<const T*, Args...>, R>>();
return ([f, cache](T* t, Args... args) {
const std::tuple<const T*, Args...> tuple(t, args...);
if (cache->find(tuple) == cache->end())
(*cache)[tuple] = (t->*f)(args...); // Insert 'tuple' as a new key in the map *cache.
return (*cache)[tuple];
});
}
template <typename Class, typename Fptr, Fptr> struct MemberFunctionMemoizer;
template <typename Class, typename R, typename... Args, R Class::*F(Args...)>
struct MemberFunctionMemoizer<Class, R (Class::*)(Args...) const, F> {
static std::function<R(Class*, Args...)>& get (const Class* p) {
static std::function<R (Args...)> memoizedF (memoizeMemberFunction(F, p));
return memoizedF;
}
};
struct FibonacciCalculator {
unsigned long calculate(unsigned num) const {
using F = MemberFunctionMemoizer<FibonacciCalculator,
unsigned long (FibonacciCalculator::*)(unsigned) const, &FibonacciCalculator::calculate>;
// return (num < 2) ? num : F::get(this)(num - 1) + F::get(this)(num - 2);
// Won't compile because F does not meet the specialization.
}
};
#include <iostream>
int main() {
FibonacciCalculator fib;
std::cout << fib.calculate(10) << '\n';
}
我在这里遗漏了什么吗?如何获得F 满足专业化要求?我尝试从图片中删除 const 限定符,但同样的问题仍然存在。
我还想保持使用成员函数指针作为模板参数的设计,即使使用非成员函数指针可以解决这个特定问题。
【问题讨论】:
-
常数。成员函数指针模板参数不是 const 限定的。另外,我认为
R Class::*F(Args...)不是指向成员函数的指针。 -
我尝试调整常量,包括使
calculate()非常量,但仍然遇到同样的问题。如何解决这个问题? -
我认为
R Class::*F(Args...)是一个返回指向成员的指针的函数,即auto F(Args...) -> R Class::*。 OTOH,R (Class::*F)(Args...)是一个指向成员函数的指针,可以是 const 限定的。 -
你的记忆似乎还是有问题,不过:coliru.stacked-crooked.com/a/a8c47b31b8a0c3a0
-
我不太明白你的代码的某些部分,我试图以一种对我来说有意义的方式来修复它:coliru.stacked-crooked.com/a/03f07a4f126cea06希望有帮助。
标签: c++ templates c++11 variadic