2016-07-06 64 views
31

比方说,我们有一个类模板,像这样:扣除功能

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的这个信息?没有必要保存模板的“设计”。

至于具体的任务,我需要设计一个类的模板。此类的对象可以在构造时为此函数提供函数和参数,并稍后调用此函数。

回答

35

不,您(当前)不能。这样做的标准方法是通过创建“make_like”功能(如make_pairmake_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这将让你做你想要什么。

+0

我相信制作这些工厂函数的正确方法是在'A '上使用'std :: decay'或类似的特征。这将使它成为'A >'。见http://en.cppreference.com/w/cpp/utility/optional/make_optional或其他'make_ *'参考 – KABoissonneault

+0

@KABoissonneault是的,如果我使用通用引用,我应该使用'std :: decay' ,我已经更新了答案。 – Holt

+0

我不太明白这个问题,所以就是答案。整个目标能够说'auto a(:: close,1)'? – Assimilater

11

您不能忽略模板类的参数,除非它们是默认的。你可以做的是有一个制造者函数,它推导出参数并将这个参数转发给模板类,返回适当实例化的对象。

template<typename F, typename... Args> 
A<F> make_A(F f, Args&&... args) { 
    return A<F>(f, std::forward<Args>(args)...); 
} 
15

由于采用模板参数扣除构造函​​数,在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副本。

+1

回复:C++ 17:这太奇怪了。看起来你至少得写'A a(:: close,1);'。虽然我想我会习惯它。 。 。 – ruakh