2016-01-21 6 views
3

Этот код дает мне ошибку в VS2015 обновления 1:не может вызывать зЬй :: функцию

ошибка C2893: Не удалось специализировать шаблон функции «Неизвестная-типа зЬй :: Invoke (_Callable & &, _Types & & ...)»

#include <iostream> 
#include <functional> 
using std::cout; 
class A 
{ 
public: 
    virtual void init() 
    { 
     cout << "A"; 
    }; 
}; 


class B 
{ 
public: 
    virtual void init() 
    { 
     cout << "B"; 
    }; 
}; 

class C : private A, private B 
{ 

    std::function<void()> a_init = &A::init; 
    std::function<void()> b_init = &B::init; 
public: 
    void call() 
    { 
     a_init(); 
     b_init(); 
    } 
}; 

int main() 
{ 
    C c; 
    c.call(); 
    return 0; 
} 

Любые идеи, если это VS компилятор глючит или мой код?
EDIT

#include "stdafx.h" 
#include <functional> 
class A 
{ 
public: 
    virtual void inita() 
    { 
     cout << "A"; 
    }; 
}; 


class B 
{ 
public: 
    virtual void initb() 
    { 
     cout << "B"; 
    }; 
}; 

class C : private virtual A, private virtual B 
{ 

    /*std::function<void()> a_init = &A::init; 
    std::function<void()> b_init = &B::init;*/ 
public: 
    void call() 
    { 
     inita(); 
    } 
}; 
+0

Это ваш код. Как вы ожидаете называть '& A :: init'? –

+0

@KerrekSB, вызывая его с помощью()? –

+3

@Thereisnothingwecando В каком экземпляре 'A'? – TartanLlama

ответ

7

Вы пытаетесь назначить не-статические функции в std::function не принимая никаких аргументов. Это не может работать, поскольку нестатические функции-члены имеют неявный параметр this.

Как это решить, зависит от того, что вы хотите сделать. Если вы хотите, чтобы вызвать хранимую функцию на произвольном объекте, подаваемом во время вызова, вам необходимо изменить std::function подписи:

std::function<void(A*)> a_init = &A::init; 

void call() 
{ 
    a_init(this); // or some other object of type A on which you want to invoke it 
} 

[Live example]

Если, с другой стороны, вы хотите позвонить она без аргументов, вы должны будете связывать объект типа A в std::function при инициализации:

std::function<void()> a_init = std::bind(&A::init, this); 

void call() 
{ 
    a_init() 
}; 

[Live example]

1

Изменение функции от virtual к static и код будет работать. Для вызова нестатической функции требуется конкретный экземпляр класса.

С другой стороны, если вы хотите использовать не статическую функцию, вы можете добавить следующий конструктор:

C(A &a, B &b) 
{ 
    a_init = std::bind(&A::init, &a); 
    b_init = std::bind(&B::init, &b); 
} 

, а затем использовать его в основной, как это:

A a; 
B b; 
C c(a, b); 
c.call(); 

EDIT :

Если публичное наследование является приемлемым вариантом, вы можете сделать это еще проще.

Constructor:

C() 
{ 
    a_init = std::bind(&A::init, this); 
    b_init = std::bind(&B::init, this); 
} 

Использование:

C c; 
c.call(); 
+0

Привет, конечно, наследующий от A означает, что у меня есть доступ к этому объекту, который создается во время создания C? Достаточно проследить ctors всех тех классов, которые участвуют в создании C, чтобы понять, что вызываются ctor класса A и ctor класса B. См. Мое редактирование. –

+0

@Thereisnothingwecando Ну, у вас будет доступ, если вы будете использовать публичное наследование. Проверьте мой обновленный ответ. –

+0

Ах да, но вы говорили: «Вам нужен конкретный экземпляр класса для вызова нестатической функции». которые, как я показал, у нас уже есть при наследовании. –

Смежные вопросы