我正在编写一个编译成C ++的编译器,并且我的C ++代码存在类型问题。该语言是懒惰的,所以我们有一个惰性值包装器,Chunk。以下是其中的一部分,以及有问题的代码:
#include <functional>
#include <memory>
template<class T>
class Chunk
{
public:
Chunk();
Chunk(std::function<T()> f);
T operator()();
std::function<T()> f_;
private:
std::shared_ptr<T> cache_;
};
template<class T>
T Chunk<T>::operator()()
{
if(cache_ == nullptr)
cache_ = std::make_shared<T>(f_());
return *cache_;
}
template<class T, class F>
T operator*(Chunk<T> t1, Chunk<F> t2)
{
return t1() * t2();
}
template<class T, class... Args>
T apply(Chunk<std::function<T(Args...)>> c, Args... as)
{
return c()(as...);
}
template<class F>
auto toChunk(F f) -> Chunk<decltype(f())>
{
return Chunk<decltype(f())>(f);
}
template<class T, class F>
struct ops
{
static const auto multiply =
toChunk([]() { return ops::multiply_; });
static const auto multiply_(Chunk<T> x, Chunk<F> y) -> decltype(x * y)
{
return x * y;
}
};
int main()
{
Chunk<double> t = toChunk([]() { return 1.0; });
Chunk<float> f = toChunk([]() { return 2.0f; });
apply(ops::multiply, t, f);
return 0;
}
我无法找出multiply
的定义,以便在没有used without template parameters
错误的情况下完成此工作。 (这里可能存在第二个问题,因为multiply_
不是std::function
,但编译器首先会缺少模板参数。)
我可以为每对类型编写很多重载,但这真的很难看。我尝试在没有模板类的情况下将模板变量相乘,即使我使用的是C ++ 14,但使用此替代定义在cannot resolve address of overloaded function
得到multiply_
:
template<class T, class F>
auto multiply_(Chunk<T> x, Chunk<F> y) -> decltype(x * y)
{
return x * y;
}
template<class T, class F>
Chunk<decltype(multiply_)> multiply = toChunk([]() { return multiply_; });
我当然将ops::multiply
更改为multiply
。有什么建议可以克服这个问题吗?
答案 0 :(得分:2)
ops
是类模板的名称。要在其定义之外引用类模板的成员,您需要指定模板参数。
如果您修复此错误,则会有更多错误。
答案 1 :(得分:0)
我最终使用了完全不同的解决方案。我通过添加第二个定义来重载apply
:
template<class F, class... Args>
auto apply(F f, Args... as) -> decltype(f(as...))
{
return f(as...);
}
简单地重写:
auto multiply = [](auto x, auto y) { return x * y; };
所以我们的库函数不会在延迟包装器中,而用户定义的函数(不能是我们语言中的模板)会。