2012-10-15 20 views
8

Ben bir parametre olarak kullanılan bir şablon std::function kabul ettiği bir fonksiyon submitAsync vardı: konuyla here benzer bir lambda (geçirerek, ancakNeden GCC, şablon argümanları açıkça belirtildiğinde, garip bir hata üretiyor ve yanlış yöntemi çağırmaya çalışıyor?

template <typename Ret, typename... Args>                                      
Future<Ret> submitAsync(const function<Ret (Args...)> &func, Args&&... args); 

, örtük şablon argümanı indirimi çalışma değildi, bu yüzden bir yapmak zorunda bir şablon parametresi olarak işlev kabul daha genel fonksiyon, daha sonra orijinal işlevine geçmek:

template <typename Func, typename... Args> 
auto submitAsync(Func &&func, Args&&... args) -> // Line 82, where the strange error occurs 
    Future< 
     typename enable_if< 
      is_convertible< 
       Func, function<decltype(func(args...)) (Args...) > 
      >::value , decltype(func(args...)) 
     >::type 
    > { 
    typedef decltype(func(args...)) ReturnType; 
    return submitAsync<ReturnType, Args...>(function<ReturnType (Args...)>(func), forward<Args>(args)...); 
} 

Bu Clang ile iyi derler, ama GCC ile aşağıdaki hata verir:

src/Scheduler.hpp: In substitution of ‘template<class Func, class ... Args> Future<typename std::enable_if<std::is_convertible<Func, std::function<decltype (func(MCServer::Scheduler::startThread::args ...))(Args ...)> >::value, decltype (func(args ...))>::type> MCServer::Scheduler::submitAsync(Func&&, Args&& ...) [with Func = int; Args = {}]’: 
src/Scheduler.hpp:91:109: required from ‘Future<typename std::enable_if<std::is_convertible<Func, std::function<decltype (func(MCServer::Scheduler::startThread::args ...))(Args ...)> >::value, decltype (func(args ...))>::type> MCServer::Scheduler::submitAsync(Func&&, Args&& ...) [with Func = MCServer::MinecraftServer::init()::<lambda()>&; Args = {}; typename std::enable_if<std::is_convertible<Func, std::function<decltype (func(MCServer::Scheduler::startThread::args ...))(Args ...)> >::value, decltype (func(args ...))>::type = int]’ 
src/MinecraftServer.cpp:237:37: required from here 
src/Scheduler.hpp:82:10: error: expansion pattern ‘#‘nontype_argument_pack’ not supported by dump_expr#<expression error>’ contains no argument packs 

Bu submitAsync(const function<Ret (Args...)> &, Args&&...) arayarak edilmelidir hatları

return submitAsync<ReturnType, Args...>(function<ReturnType (Args...)>(func), forward<Args>(args)...); 

, aslında geçirilen func tipi int olduğu gibi çalışmıyor tabii ki, submitAsync(Func &&func, Args&&... args) aramaya çalışıyor öncelikle göstermektedir. Hatanın son kısmı da anlamıyorum, expansion pattern ‘#‘nontype_argument_pack’ not supported by dump_expr#<expression error>’ contains no argument packs (belki de derleyici bir hata olabilir) (satır 82, işaretin işaretlenmesi için bir yorum yazmamın ana kısmıdır)? Garip

, ben bu çizgiyi yerine submitAsync çağrısında açık şablon parametreleri kaldırdığınızda: bununla

return submitAsync<ReturnType, Args...>(function<ReturnType (Args...)>(func), forward<Args>(args)...); 

:

return submitAsync(function<ReturnType (Args...)>(func), forward<Args>(args)...); 

GCC onu doğru derler. Peki, neden argümanları çıkarmasına izin verildiğinde iyi çalışıyor olsa da, GCC şablon argümanları belirtildiğinde yanlış işlevi çağırıyor? Ve herkes 82 numaralı çizgi ile ilgili garip hatanın ne olduğunu söyleyebilir mi?

Düzenleme: GCC 4.7.2

DÜZENLEME 2 kullanıyorum, söz unuttum: Daha fazla test üzerine solution and explanation here

+2

O. Hangi GCC sürümünü kullanıyorsunuz? –

+0

Oh evet, GCC 4.7.2 kullanıyorum unuttum. –

+1

* 'nontype_argument_pack' desteklenmiyor * derleyici bu özel özellik için henüz desteği olmadığını gösteriyor gibi görünüyor ... –

cevap

1

, ben açık şablon parametreleri olmadan Clang ve KİK hem olmadığını anladı ettik Aslında istediğim gibi çalışıyorum. Her iki durumda da, işlev kendisini sadece parametrelere uyan ilk işlev olarak çağırıyordu. Bir şablon parametresi const std::function& alanından daha iyi bir eşleşme olduğundan işlevi alan derleyicinin submitAsync kararını vermesinden kaynaklandı. Şimdi submitAsync referans olarak işlev almaya olduğunu değiştirdikten sonra çalışıyor: garip hata derleyici sorunu benziyor

template <typename Ret, typename... Args> 
Future<Ret> Scheduler::submitAsync(function<Ret (Args...)> func, Args&&... args) 
İlgili konular