2016-11-29 3 views
8

मैं सिर्फ किताब "प्रैक्टिकल सी ++ Metaprogramming" पढ़ सकते हैं और यह निम्न उदाहरण है कि मैं संकलन नहीं कर सकता है। क्या आप इसे मेरे लिए हल करने में मदद कर सकते हैं।प्रैक्टिकल सी ++ Metaprogramming

template <typename F> 
struct make_tuple_of_params; 

template <typename Ret, typename... Args> 
struct make_tuple_of_params<Ret (Args...)> 
{ 
    using type = std::tuple<Args...>; 
}; 

template <typename F> 
using make_tuple_of_params_t = typename make_tuple_of_params<F>::type; 

template<typename F> 
void some_magic_function(F callable) 
{ 
    make_tuple_of_params_t<F> tuple; 
    /* 
    ... do something with arguments in tuple... 
    */ 
} 

int main() 
{ 
    some_magic_function([] (int, double, float) {}); 
} 

मैं कह रहा एक संकलन त्रुटि मिलती है: 'प्रकार' 'make_tuple_of_params' के किसी भी प्रत्यक्ष या अप्रत्यक्ष आधार वर्ग का सदस्य नहीं है। यह SFINAE की तरह सीम की अपेक्षा की जाती है क्योंकि डिफ़ॉल्ट संरचना का चयन किया जाता है। मैं यह कैसे तय करुं?

+0

एक लैम्ब्डा प्रकार एक समारोह प्रकार नहीं है। – aschepler

+1

ध्यान रखें कि C++ 14 में lambdas में 'auto' पैरामीटर हो सकते हैं जिन्हें स्पष्ट रूप से टेम्पलेट किए गए फ़ैक्टर के रूप में माना जा सकता है। इस प्रकार के लैम्बडास के लिए आप अपने ट्यूपल प्रकार को समान रूप से क्या उम्मीद करेंगे? –

+2

कोई SFINAE, ऊपर है बस विशेषज्ञता टेम्पलेट – Yakk

उत्तर

5

lambdas के लिए ऑटो मानकों के साथ lambdas वैकल्पिक हल सहित नहीं इस प्रकार दे सकता है:

#include <tuple> 
#include <typeinfo> 
#include <iostream> 

template <class> 
struct make_tuple_of_params; 

template <class Res, class Type, class... Args> 
struct make_tuple_of_params<Res (Type::*)(Args...) const> { 
    using type = std::tuple<Args...>; 
}; 

template <class F> 
using make_tuple_of_params_t = typename make_tuple_of_params<F>::type; 

template<typename F> 
void some_magic_function(F callable) 
{ 
    make_tuple_of_params_t<decltype(&F::operator())> tuple; 
    std::cout << typeid(tuple).name() << std::endl; 
} 

int main() 
{ 
    some_magic_function([] (int, double, float) {}); 
} 

[live demo]

6

[] (int, double, float) {} का प्रकार एक अज्ञात वर्ग प्रकार स्थानीय है main, जिसे बंद करने का प्रकार कहा जाता है। यह निश्चित रूप से void (int, double, float) है; यह वास्तव में एक समारोह प्रकार नहीं है। इसलिए, फ़ंक्शन प्रकारों के लिए विशेषज्ञता लागू नहीं होती है, और प्राथमिक टेम्पलेट का चयन किया जाता है। (ध्यान दें कि आपके कोड में कोई SFINAE शामिल नहीं है)।

इसे ठीक करने के लिए के रूप में: मैं वहाँ एक पूरी तरह से सामान्य समाधान नहीं लगता। किसी विशेष some_magic_function के लिए समाधान/समाधान हो सकता है, लेकिन यह उस कार्य पर निर्भर करेगा जो आपको करने के लिए आवश्यक है।

+1

मिलान संभावित सुधारों के बारे में पैटर्न: कुछ भी नहीं है पर कब्जा कर लिया जाना आवश्यक है या '+ [] (पूर्णांक, डबल, नाव) के साथ एक समारोह सूचक में लैम्ब्डा टर्निंग {}' एक विकल्प हो सकता है। बेशक, 'make_tuple_of_params' को फ़ंक्शन पॉइंटर्स और फ़ंक्शन प्रकारों से मेल खाना चाहिए। –

+0

ठीक है मैंने एक फ़ंक्शन पॉइंटर के साथ प्रयास किया लेकिन सफल नहीं हुआ। – 0xBADF00

+0

@ 0xBADF00 यह मार्कस की टिप्पणी की दूसरी वाक्य में शामिल है। – Yakk

संबंधित मुद्दे