2014-02-07 111 views
2

這裏是代碼。它不會在vs2013編譯,但在gcc4.8std線程調用模板模板類的成員函數:編譯器錯誤

錯誤C2665並編譯:「的std ::螺紋::線程」:沒有4個重載可以轉換所有的參數類型

由於我使用vs2013,任何人都可以提供解決方法嗎?

#include <iostream> 
#include <thread> 

template<typename T> 
class TestClass 
{ 
public: 
    TestClass(){}; 
    ~TestClass(){}; 

    T t; 

    template<typename U> 
    void fun(U u) 
    { 
     std::cout << "fun: " << u << '\n'; 
    } 
}; 

int main() 
{ 
    TestClass<double> A; 

    auto aaa = std::thread(&TestClass<double>::fun<int>, &A, 1); 
} 
+0

不調用'加入()'或'分離()'在線程結束之前是未定義的行爲 –

+0

你應該調用'join()'。 – BlackMamba

+2

@KoushikShetty,實際上,不調用'join()'或'detach()'不是未定義的行爲。它會導致對'terminate()'的調用。 (這比未定義的行爲更好,因爲你始終會發生進程崩潰,所以你可以去修復它。) –

回答

7

你可以簡單地使用lambda,而不是成員函數指針的胡鬧:

auto aaa = thread([&]{ A.fun(1); }); 
aaa.join(); 
+0

太棒了。它適用於vs2013 – liangbright

2

還有另一種方法可以實現上述的問題,如果你不介意! 首先只看線程對象的顯式構造:

template< class Function, class... Args > 
explicit thread(Function&& f, Args&&... args); 

˚F - 爲函數對象通用引用。

args - 函數的可變參數(函子)f

(我不打算更深入地解釋這裏使用的可變參數調用)。 所以,現在我們知道我們能對付仿函數,因此, 定義仿函數(函數對象)象下面這樣:

template<typename T> 
class TestClass 
{ 
public: 
    TestClass(){}; 
    ~TestClass(){}; 

    T t; 

    template<typename U> 
    void operator()(U u1,U u2){ 
     std::cout << "fun: " << u1*u2 << '\n'; 
    } 

}; 
int main() 
{ 
    TestClass<double> A; 
    auto aaa = std::thread(A,1,100);// calling functor A(1,100) 
    aaa.join() 
    //or if you can move object from main thread to manually created thread aaa ,it's more elegant. 
    auto aa = std::thread(std::move(A),1,100); 
    aa.join(); 
    A(1, 99); 
    system("Pause"); 
    return 0; 
} 

//請注意這裏我沒有用任何更衣室防範系統。 如果使用靜態功能,您不必各自的情況下,每個時間可能因此改變你的預期運行時行爲,你必須管理結合,

template<typename U> 
    static void fun(U u) 
    { 
     std::cout << "fun: " << u << '\n'; 
    } 
then invoke the function, 
int main() 
{ 
    TestClass<double> A; 
    auto aaa = std::thread(&TestClass<double>::fun<int>, 1); 
    system("Pause"); 
    return 0; 
}