为什么在将i传递给构造函数时以下代码不能编译。其他类似的构造会被编译。
#include <iostream>
#include <functional>
int RetXPrintU(int x, uint u)
{
std::cout << "RetXprintU(): " << u << std::endl;
return x;
}
template <typename Fn, typename... Args>
void Call(Fn&& fun, Args&&... args)
{
std::invoke(std::forward<Fn>(fun), std::forward<Args>(args)...);
}
template <typename Fn, typename... Args>
class CallableObj
{
public:
explicit CallableObj(Fn&& fun, Args&&... args)
{
std::invoke(std::forward<Fn>(fun), std::forward<Args>(args)...);
}
};
int main() {
int i = 4;
std::invoke(RetXPrintU, i, 8u);
Call(RetXPrintU, i, 8u);
CallableObj co(RetXPrintU, i, 8u); // WHY I DO NOT COMPILE?
//CallableObj co(RetXPrintU, 0, 8u); // WHY I COMPILE?
return 0;
}发布于 2020-01-14 23:18:21
正如错误消息所说,编译器无法推导出CallableObj的模板参数。为此,您需要添加一个扣减指南:
template <typename Fn, typename... Args>
CallableObj(Fn&& fun, Args&&... args) -> CallableObj<Fn, Args>...>;整个代码是这样写的:
template <typename Fn, typename... Args>
class CallableObj
{
public:
explicit CallableObj(Fn fun, Args... args)
{
std::invoke(std::forward<Fn>(fun), std::forward<Args>(args)...);
}
};
template <typename Fn, typename... Args>
CallableObj(Fn&& fun, Args&&... args) -> CallableObj<Fn, Args...>;正如@Jarod42指出的那样,没有必要让构造函数本身成为模板(就像在答案的第一个版本中一样)。
这是一个live example (由@jarod42修正的版本)。
我假设您的代码只是一个最小的示例,并且您需要将类作为模板。如果不是这样,你最好使用另一种解决方案。
发布于 2020-01-14 23:18:36
这里的问题是您需要将模板从类移动到构造器。当你有了
template <typename Fn, typename... Args>
class CallableObj
{
public:
explicit CallableObj(Fn&& fun, Args&&... args)
{
std::invoke(std::forward<Fn>(fun), std::forward<Args>(args)...);
}
};Args&&...不是可变转发引用,因为它是为类本身推导的,并且当您调用CallableObj co(RetXPrintU, i, 8u);时,类被实例化,构造函数被标记为
explicit CallableObj(int(int, unsigned int)&& fun, int&& arg1, unsigned int&& arg2)我们想要的是
class CallableObj
{
public:
template <typename Fn, typename... Args>
explicit CallableObj(Fn&& fun, Args&&... args)
{
std::invoke(std::forward<Fn>(fun), std::forward<Args>(args)...);
}
};因此,现在当构造函数被调用时,Args将被推导出来,而Args&&现在是一个转发引用。
CallableObj co(RetXPrintU, 0, 8u);在你的例子中工作的原因是因为0是一个prvalue,并且prvalue可以绑定到一个rvalue引用。
https://stackoverflow.com/questions/59736558
复制相似问题