मेरा कोड और समस्याएं इस प्रकार हैं:

template <typename T, typename Func> class StepRange {
public:
  template <
      std::enable_if_t<std::is_invocable_r_v<T, Func, const T &>, int> = 0>
  StepRange(T start, T stop, Func func)
      : start_(std::move(start)), stop_(std::move(stop)), val_(start),
        func_(std::move(func)) {}
  template <typename Step>
  StepRange(T start, T stop, Step step)
      : start_(std::move(start)), stop_(std::move(stop)), val_(start), 
        func_(std::function<T(const T &)>{
          [step](const T &val) { return val + step; }}) {}

private:
  T start_, stop_, val_;
  Func func_;
};

auto r = StepRange(1, 1, [](int val) { return val + 1;});
// since c++17 it works fine
auto t = StepRange(1, 1, 1);
// it does not compile and compiler says that it couldn't infer template argument 'Func'

तो मैं कंपाइलर को 'फनक' के प्रकार का अनुमान लगाने में मदद करने के लिए कुछ अतिरिक्त तरीकों का उपयोग कैसे कर सकता हूं?

0
inhzus 1 अप्रैल 2020, 11:16
इसके अलावा: लैम्ब्डा को std::function में क्यों लपेटें? आप इससे आगे बढ़ने के बाद start का उपयोग कर रहे हैं, आपको val_ की आवश्यकता क्यों है?
 – 
Caleth
1 अप्रैल 2020, 13:49
यह इंगित करने के लिए धन्यवाद कि मुझे लैम्ब्डा को std::function में लपेटने की आवश्यकता नहीं है। जहां तक ​​val_ का सवाल है, यह संदर्भ-निर्णय है, क्योंकि StepRange वर्ग एक स्टेट मशीन की तरह है और val_ स्थिति को चिह्नित करने के लिए आवश्यक है।
 – 
inhzus
2 अप्रैल 2020, 14:09

1 उत्तर

सबसे बढ़िया उत्तर

कंपाइलर आपके दूसरे कंस्ट्रक्टर से Func निकालने में सक्षम नहीं है, इसलिए आपको यह बताना होगा कि Func क्लास पैरामीटर कैसे निर्धारित किया जाए जब पहला कंस्ट्रक्टर व्यवहार्य न हो। आप कटौती गाइड जोड़कर ऐसा कर सकते हैं:

template<typename T, typename Step, std::enable_if_t<!std::is_invocable_r_v<T, Step, const T &>, int> = 0>
StepRange(T, T, Step) -> StepRange<T, std::function<T(const T&)>>;

जब भी पहला कंस्ट्रक्टर अक्षम होता है, तो यह Func को std::function<T(const T&)> में घटा देगा।

या, यदि आप वास्तव में केवल दूसरे कंस्ट्रक्टर का उपयोग करना चाहते हैं यदि तीनों तर्कों के प्रकार मेल खाते हैं, तो आप इसके बजाय लिख सकते हैं

template<typename T>
StepRange(T, T, T) -> StepRange<T, std::function<T(const T&)>>;

बेशक कुछ किनारे के मामले हैं जिन पर किसी भी मामले में विचार किया जाना है।

3
Jarod42 1 अप्रैल 2020, 11:44
मैं आपके उत्तर के बिना उपयोगकर्ता-परिभाषित कटौती मार्गदर्शिकाएँ नहीं जान पाऊँगा! मदद के लिये शुक्रिया!
 – 
inhzus
1 अप्रैल 2020, 11:40