2016-07-06 66 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