Desidero eseguire il bind()
sulla versione della funzione della classe base della classe derivata. La funzione è contrassegnata protetta nella base. Quando faccio così, il codice viene compilato felicemente in Clang (Apple LLVM Compiler 4.1) ma dà un errore sia in g ++ 4.7.2 che in Visual Studio 2010. L'errore è simile a: "'Base :: foo': impossibile accesso protetto membro. "std :: bind() - utilizzo di una funzione membro protetto di base dalla funzione membro di una classe derivata
L'implicazione è che il contesto per il riferimento è effettivamente all'interno di bind()
, dove ovviamente la funzione è vista come protetta. Ma non dovrebbe bind()
ereditare il contesto della funzione di chiamata - in questo caso, Derived::foo()
- e quindi vedere il metodo di base come accessibile?
Il seguente programma illustra il problema.
struct Base
{
protected: virtual void foo() {}
};
struct Derived : public Base
{
protected:
virtual void foo() override
{
Base::foo(); // Legal
auto fn = std::bind(&Derived::foo,
std::placeholders::_1); // Legal but unwanted.
fn(this);
auto fn2 = std::bind(&Base::foo,
std::placeholders::_1); // ILLEGAL in G++ 4.7.2 and VS2010.
fn2(this);
}
};
Perché la discrepanza nel comportamento? Che è corretto? Quale soluzione alternativa è disponibile per i compilatori che generano errori?
È intenzionale che "Derived :: foo" si chiami o sia solo un risultato della semplificazione per un esempio? – aschepler
@aschepler Questa è la parte "indesiderata" di "legale ma indesiderata". – OldPeculier