【发布时间】:2021-11-01 07:11:51
【问题描述】:
我创建了一个模板类,其中构造函数接受一个 std::function 对象。 第一个模板参数表示该函数的返回值。 第二个参数定义了该函数的参数类型。
#include <functional>
//Base
template<class R, class Arg>
class Executor {
public:
Executor(std::function<R(Arg)> function)
: mFunction(function)
{}
private:
std::function<R(Arg)> mFunction;
};
//Specialization1
template<class Arg>
class Executor<void, Arg> {
public:
Executor(std::function<void(Arg)> function)
: mFunction(function)
{}
private:
std::function<void(Arg)> mFunction;
};
//Specialization2
template<class R>
class Executor<R, void> {
public:
Executor(std::function<R()> function)
: mFunction(function)
{}
private:
std::function<R()> mFunction;
};
int testBase(float value) {
return 5;
}
void testSpecialization1(float value) {}
int testSpecialization2() {
return 22;
}
int main() {
Executor executorBase{std::function(testBase)};
Executor executorSpecialization1{std::function(testSpecialization1)};
//Executor<int, void> executorSpecialization2{std::function(testSpecialization2)}; // Compiles
Executor executorSpecialization2{std::function(testSpecialization2)}; // Doesn't compile. Uses Base. template<class R, class Arg>
}
在使用函数 std::function
main.cpp: In function 'int main()':
main.cpp:55:72: error: class template argument deduction failed:
55 | Executor executorSpecialization2{std::function(testSpecialization2)}; // Doesn't compile. Uses Base. template<class R, class Arg>
| ^
main.cpp:55:72: error: no matching function for call to 'Executor(std::function<int()>)'
main.cpp:7:9: note: candidate: 'template<class R, class Arg> Executor(std::function<R(Arg)>)-> Executor<R, Arg>'
7 | Executor(std::function<R(Arg)> function)
| ^~~~~~~~
main.cpp:7:9: note: template argument deduction/substitution failed:
main.cpp:55:72: note: candidate expects 1 argument, 0 provided
55 | Executor executorSpecialization2{std::function(testSpecialization2)}; // Doesn't compile. Uses Base. template<class R, class Arg>
| ^
main.cpp:5:7: note: candidate: 'template<class R, class Arg> Executor(Executor<R, Arg>)-> Executor<R, Arg>'
5 | class Executor {
| ^~~~~~~~
main.cpp:5:7: note: template argument deduction/substitution failed:
main.cpp:55:72: note: 'std::function<int()>' is not derived from 'Executor<R, Arg>'
55 | Executor executorSpecialization2{std::function(testSpecialization2)}; // Doesn't compile. Uses Base. template<class R, class Arg>
|
它尝试使用基本版本。但当然缺少第二个参数。 如果我指定它编译的模板参数。
那么为什么要为 executorSpecialization2 选择基本模板呢? 是否甚至可以在不需要传递模板参数的情况下对 void 使用类型推导?
谢谢
【问题讨论】:
-
FWIW,您不需要专门化,只需将
Arg设为可变参数模板参数即可。工作示例:coliru.stacked-crooked.com/a/8f8de3559302388e