2016-01-21 79 views
3

此代碼給我錯誤在VS2015更新1:不能調用的std ::功能

錯誤C2893:無法專注函數模板「未知類型 的std ::調用(_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的編譯器是車還是我的代碼的任何想法?
編輯

#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

變化從virtualstatic和代碼將工作中的作用。你需要一個類的特定實例來調用一個非靜態函數。

在另一方面,如果你希望使用非靜態功能,您可以添加下面的構造:

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(); 

編輯:

如果公共繼承是可以接受的選項,那麼你可以做得更簡單。

構造:

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

用法:

C c; 
c.call(); 
+0

嗨,肯定從A繼承意味着我可以訪問該對象,這是創建C期間創建的?跟蹤創建C所涉及的所有類的Ctors,足以認識到調用了A類的類和C類的Ctor。看我的編輯。 –

+0

@Thereisnothingwecando如果您要使用公有繼承,那麼您將可以訪問。檢查我更新的答案。 –

+0

啊,是的,但你說:「你需要一個類的特定實例來調用一個非靜態函數。」正如我所展示的,我們在繼承時已經有了。 –