2016-06-09 16 views
6

neden görünmüyor şu işleri: AçıkçasıHata ayıklama şablon kesinti arızası

std::string fn(int i) 
{ 
     sleep(i); // number of seconds to sleep for 
     std::cout << "Exiting after pausing " << i << " seconds\n"; 
     return std::to_string(i+1); 
} 

template<typename T, typename U> 
int simult(std::function<T(U)> f, std::vector<U> args) 
{ 
     return 666; 
} 


int main() 
{ 

     std::vector<int> args { 6, 5, 7 };   
     int r = simult(fn, args); 
} 

Fonksiyon simult tamamlanmadı: Sadece bu aşamada derlemek için bir şeyler almaya çalışıyorum. Buradaki fikir, bir işlev ve bir args listesi sağlamanızdır ve simdişler, parçalanmış aramaları kullanarak parçalara ayrılır.

Bu aşamada, derleme sorununu çözmeye çalışıyorum.

simult.cc: In function ‘int main()’: 
simult.cc:43:25: error: no matching function for call to ‘simult(std::__cxx11::string (&)(int), std::vector<int>&)’ 
    int r = simult(fn, args); 
         ^
simult.cc:23:5: note: candidate: template<class T, class U> int simult(std::function<T(U)>, std::vector<U>) 
int simult(std::function<T(U)> f, std::vector<U> args) 
    ^~~~~~ 
simult.cc:23:5: note: template argument deduction/substitution failed: 
simult.cc:43:25: note: mismatched types ‘std::function<T(U)>’ and ‘std::__cxx11::string (*)(int) {aka std::__cxx11::basic_string<char> (*)(int)}’ 
    int r = simult(fn, args); 
         ^
+0

için std::vector<U> args değişti! Öncelikle bir fonksiyon göstergesinde geçen, şablon tipini belirlemesi gereken bir 'std :: function <>' a atamak zorunda mı? – Nim

+0

Ha. Her zaman 666'yı bir test tamsayı olarak kullanırım. Bu gerekçelerle bunu beğendim, artı bir tane. – Bathsheba

+0

@Bathsheba aslında kutsal metinlerin% 80'inde 616'dır ve 666 değil, bu yüzden endişelenecek bir şey yok ... – 101010

cevap

1

Şablon kesintiler örtük dönüştürme tetiklemez. İşlev (işaretçi) türü dönüştürülebilir - std::function olmasına rağmen, bu dönüştürme hiçbir zaman şablon değiştirme işleminin bir parçası değildir.

Sen std::function inşa etmek ve simlut onu geçmek zorunda kalacak:

int r = simult(std::function<std::string (int)>(fn), args); 
+0

Ve downvote nedeni nedir? – SergeyA

1

dolayı kullanıcı tanımlı dönüşümler şablon argümanı kesintinin kabul edilmez gerçeğine çalışmaz.

Açıkça şablon argümanları sağlayarak derleyici yardımcı ve aynı simult diyebiliriz ya:

int r = simult<std::string, int>(fn, args); 

Live Demo

Yoksa aşağıdaki gibi decltype kullanımı ile çalışmak yapabiliriz:

Live Demo

Düzenleme:

bir std::vector<T> sizin derleyici aşağıdaki gibi değiştirebilirsiniz 14 C++ desteklemesi koşuluyla geri dönmek isterseniz:

template<typename T, typename U> 
std::vector<T> simult_impl(std::function<T(U)> f, std::vector<U> const &args) { 
    return std::vector<T>(10, T{"666"}); 
} 

template<typename F, typename U> 
auto simult(F f, std::vector<U> const &args) { 
    return simult_impl<decltype(f(args[0])), U>(f, args); 
} 

Live Demo

+0

Özellikle ikinci bölümünüzü beğeniyorum, sonuçta bir 'int' döndürmek istemiyorum, geri döndüğüm işlevin nasıl tanımlandığına bağlı olarak std :: vector 'dönmek istiyorum. – blippy

+0

@blippy see edit – 101010

+0

Çok teşekkürler. Kontrol edeceğim. Evet, bir C++ 14 derleyicim var. – blippy

1

@SergeyA gelen öneri kullanarak, Çalışma kodu ile geldim, şimdi tam bir örnek olarak:

#include <functional> 
#include <iostream> 
#include <string> 
#include <future> 
#include <thread> 
#include <vector> 

#include <unistd.h> // for sleep. Not needed generally 

// declare a function that does what you want 
std::string fn(int i) 
{ 
     sleep(i); // number of seconds to sleep for 
     std::cout << "Exiting after pausing " << i << " seconds\n"; 
     return std::to_string(i+1); 
} 



template<typename T, typename U> 
std::vector<T> simult(std::function<T(U)> func, std::vector<U> const &args) 
{ 
     std::vector<std::future<T>> fs; 
     for(auto& a:args) fs.push_back(std::async(func, a)); 

     std::vector<T> results; 
     for(auto &f:fs) results.push_back(f.get()); 
     return results; 
} 



int main() 
{ 
     std::vector<int> args { 6, 5, 7 }; 
     std::vector<std::string> results = simult(std::function<std::string (int)>(fn), args); 
     std::cout << "Results are:\n"; 
     for(auto&r:results) std::cout << r << "\n"; //results are returned in correct order 
     return 0; 
} 

Compil E:

g++ simult.cc -o simult -lpthread 

çalıştırın:

time -p simult 
Exiting after pausing 5 seconds 
Exiting after pausing 6 seconds 
Exiting after pausing 7 seconds 
Results are: 
7 
6 
8 
real 7.00 
user 0.00 
sys 0.00 

ben biraz C++ tek başına fonksiyonun türünü anlamak edemez neden olarak şaşkın hala değilim, ama önemli şey tahmin öyle Eserleri. Sadece arayanın gereksiz yere bana verdiği gibi görünüyor.

Düzenleme: fonksiyonu simult() yılında T ile std::string örneklerini yerini aldı.

Düzenleme: std::vector<U> const &args

gerçekten derleyici herhangi bir yardım vermiyorsun