我已經寫了下面的實現一個通用的信號/槽系統完美轉發:的variading模板參數
Signal<int> signal;
// Case 1
signal(0);
//Case 2
int i(0);
signal(i);
:
template< typename... Args >
class Signal : NonCopyable
{
public:
typedef std::function< void (Args...) > Delegate;
void connect(const Delegate& delegate);
void operator()(Args&&... args) const;
private:
std::list<Delegate> _delegates;
};
template< typename... Args >
void Signal<Args...>::connect(const Delegate& delegate)
{
_delegates.push_front(delegate);
}
template< typename... Args >
void Signal<Args...>::operator()(Args&&... args) const
{
for (const Delegate& delegate : _delegates)
delegate(std::forward<Args>(args)...);
}
後來,我用下面簡單的情況下測試了我的班案例1編譯沒有問題。個案2中,另一方面,會生成以下錯誤GCC 4.7.2下:
/home/pmjobin/Workspace/main.cpp:1196:10: error: cannot bind ‘int’ lvalue to ‘int&&’
/home/pmjobin/Workspace/main.cpp:82:6: error: initializing argument 1 of ‘void Signal<Args>::operator()(Args&& ...) const [with Args = {int}]’
我理解這個問題有事情做完美轉發(和我後面的誤解)。但是,我從std :: make_shared()& std :: make_tuple()實現中激發了我自己,並且我沒有看到將可變參數轉發給委託的方式有任何區別。唯一明顯的區別是make_shared()和make_tuple()都是函數模板,而不是像上面的Signal實現那樣的類模板。
- 編輯 -
在應對各種意見,這裏是信號類實現不從上述問題的影響的新版本。此外,現在可以使用connect函數返回的不透明令牌斷開委託。結果可能不像其他實現那樣靈活和強大(比如boost :: signal),但至少它具有簡單和輕量級的優點。
template< typename Signature >
class Signal : NonCopyable
{
public:
typedef std::function<Signature> Delegate;
class DisconnectionToken
{
DisconnectionToken(typename std::list<Delegate>::iterator it)
: _it(it)
{}
typename std::list<Delegate>::iterator _it;
friend class Signal;
};
DisconnectionToken connect(const Delegate& delegate);
void disconnect(DisconnectionToken& token);
template< typename... Args >
void operator()(Args&&... args) const;
private:
std::list<Delegate> _delegates;
};
template< typename Signature >
typename Signal<Signature>::DisconnectionToken Signal<Signature>::connect(const Delegate& delegate)
{
_delegates.push_front(delegate);
return DisconnectionToken(_delegates.begin());
}
template< typename Signature >
void Signal<Signature>::disconnect(DisconnectionToken& token)
{
if (token._it != _delegates.end())
{
_delegates.erase(token._it);
token._it = _delegates.end();
}
}
template< typename Signature >
template< typename... Args >
void Signal<Signature>::operator()(Args&&... args) const
{
for (const Delegate& delegate : _delegates)
delegate(std::forward<Args>(args)...);
}
'Args && ... args'基本上是'int && args'。 – Nawaz
@Nawaz是的,我錯過了他明確指出它上面。沒關係我剛纔說的。是的,完美的轉發主要只在您讓模板類型被推導時纔有效。 –
OP需要(或_can_)做的是爲operator()提供單獨的'參數...'。 –