मेरे पास निम्नलिखित छोटा कार्यक्रम है:

#include <iostream>

class Field1 {
    using Self_t = Field1;

public:
    template<unsigned int KEY, std::enable_if_t<KEY == 1, Self_t>*>
    int get() {
        return 1;
    }
};

class Field2 {
    using Self_t = Field2;

public:
    template<unsigned int KEY, std::enable_if_t<KEY == 2, Self_t>*>
    char get() {
        return 'a';
    }
};

template<typename FIRST, typename ... REST>
class _Container<FIRST, REST...> : public FIRST, public REST ... {
    using FIRST::get;
    using REST::get ...;
};

template<typename ... FIELDS>
class Container: public _Container<FIELDS...> {};

int main(int, char*[]) {
    Container<Field1, Field2> fred;
    std::cout << fred.get<1>() << std::endl;
    return 0;
}

जीसीसी 10.2.0 से आउटपुट है

   ./src/main.cpp: In function ‘int main(int, char**)’:
../src/main.cpp:34:27: error: no matching function for call to ‘Container<Field1, Field2>::get<1>()’
   34 |  std::cout << fred.get<1>() << std::endl;
      |                           ^
../src/main.cpp:8:6: note: candidate: ‘template<unsigned int KEY, std::enable_if_t<(KEY == 1), Field1>* <anonymous> > int Field1::get()’
    8 |  int get() {
      |      ^~~
../src/main.cpp:8:6: note:   template argument deduction/substitution failed:
../src/main.cpp:34:27: note:   couldn’t deduce template parameter ‘<anonymous>’
   34 |  std::cout << fred.get<1>() << std::endl;
      |                           ^
../src/main.cpp:17:7: note: candidate: ‘template<unsigned int KEY, std::enable_if_t<(KEY == 2), Field2>* <anonymous> > char Field2::get()’
   17 |  char get() {
      |       ^~~
../src/main.cpp:17:7: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/10.2.0/bits/move.h:57,
                 from /usr/include/c++/10.2.0/bits/nested_exception.h:40,
                 from /usr/include/c++/10.2.0/exception:148,
                 from /usr/include/c++/10.2.0/ios:39,
                 from /usr/include/c++/10.2.0/ostream:38,
                 from /usr/include/c++/10.2.0/iostream:39,
                 from ../src/main.cpp:1:
/usr/include/c++/10.2.0/type_traits: In substitution of ‘template<bool _Cond, class _Tp> using enable_if_t = typename std::enable_if::type [with bool _Cond = false; _Tp = Field2]’:
../src/main.cpp:16:69:   required from here
/usr/include/c++/10.2.0/type_traits:2554:11: error: no type named ‘type’ in ‘struct std::enable_if<false, Field2>’
 2554 |     using enable_if_t = typename enable_if<_Cond, _Tp>::type;
      |           ^~~~~~~~~~~

क्लैंग त्रुटि संदेशों का एक अधिक संघनित सेट उत्पन्न करता है:

../src/main.cpp:36:20: error: no matching member function for call to 'get'
        std::cout << fred.get<1>() << std::endl;
                     ~~~~~^~~~~~
../src/main.cpp:9:6: note: candidate template ignored: couldn't infer template argument ''
        int get() {
            ^
../src/main.cpp:19:7: note: candidate template ignored: couldn't infer template argument ''
        char get() {
             ^

जहां तक ​​मैं समझ सकता हूं, प्रत्येक get फ़ंक्शन की टेम्प्लेट पैरामीटर सूचियां अलग हैं और fred के लिए get को हल करने का प्रयास करते समय, सभी get फ़ंक्शन आधार वर्गों में समान उम्मीदवार माने जाते हैं। मेरा इरादा यह है कि get कार्यों में से एक को छोड़कर सभी SFINAE विफल हो जाएं। ऐसा होता नहीं दिख रहा है।

मैंने स्पष्ट रूप से यहाँ कुछ महत्वपूर्ण गलत समझा है। क्या कोई मुझे सही दिशा दिखा सकता है?

0
Nicole 9 पद 2020, 03:14

1 उत्तर

सबसे बढ़िया उत्तर
template<unsigned int KEY, std::enable_if_t<KEY == 1, Self_t>*>
int get() {
  return 1;
}
    
// ...

f.get<1>();

यह फ़ंक्शन दो टेम्पलेट पैरामीटर लेता है, लेकिन आपने केवल एक प्रदान किया है। फ़ंक्शन को कॉल करते समय या तो दूसरा पास करें, या दूसरे टेम्प्लेट पैरामीटर के लिए एक डिफ़ॉल्ट तर्क प्रदान करें ताकि केवल एक की आवश्यकता हो। मुझे यहां Self_t की आवश्यकता भी नहीं दिख रही है।

template <unsigned int KEY, std::enable_if_t<KEY == 1>* = nullptr>
int get() {
  return 1;
}
2
N. Shead 9 पद 2020, 00:29