我们假设我们有一个类模板:
template<typename F>
class A
{
public:
template<typename... Args>
A(F f, Args... args)
{ /* Do something... */ }
};
现在我想以某种方式使用它:
A<int(int)> a(::close, 1);
现在的问题是:有没有办法省略<int(int)>
,因为编译器可以知道::close
的这些信息?没有必要保存&#34; design&#34;模板。
至于具体的任务,我需要设计一个类的模板。该类的对象可以在构造时获取该函数的函数和参数,并稍后调用该函数。
答案 0 :(得分:35)
不,你(目前)不能。这样做的标准方法是创建“make_like”函数(例如make_pair
,make_optional
...):
template<typename F, typename... Args>
A<std::decay_t<F>> make_A (F &&f, Args&&... args) {
return {std::forward<F>(f), std::forward<Args>(args)...};
}
C ++ 17将引入template argument deduction for class,这将允许您完全按照自己的意愿行事(另请参阅下面的Barry's answer)。
答案 1 :(得分:16)
由于采用了构造函数的模板参数推导,在C ++ 17中,您将能够只写:
A a(::close, 1);
在此之前,你只需要写一个工厂来为你做演绎:
template <class F, class... Args>
A<std::decay_t<F>> make_a(F&& f, Args&&... args) {
return {std::forward<F>(f), std::forward<Args>(args)...};
}
auto a = make_a(::close, 1);
这有点冗长,但至少你不需要担心效率 - 由于RVO,这里不会有副本。
答案 2 :(得分:11)
您不能省略模板类的参数,除非它们是默认的。你可以做的是有一个maker函数,它推导出参数并将这个参数转发给模板类,返回一个适当实例化的对象。
template<typename F, typename... Args>
A<F> make_A(F f, Args&&... args) {
return A<F>(f, std::forward<Args>(args)...);
}