Вызов и перегруженная функция шаблона - PullRequest
3 голосов
/ 21 марта 2019

Предполагая, что у меня есть 2 перегруженных метода в классе, показанном ниже. Пожалуйста, игнорируйте необходимость такой странной перегрузки методов, с которой я недавно столкнулся

    class A{
      public:

        //Lets call this method 1
        int GetVal(bool isCondition) const
        {
             //do something and return val
        }

        //Lets call this method 2
        template<typename T>
        int GetVal(T expression)
        {
            //do something using expression
            //and return val
        }

    };

int main()
{
    A obj;
    int val = obj.GetVal(false) << std::endl; //I want to invoke method 1
}

В функции main() я хочувызывать метод1, а не метод2.Как мне этого добиться?Спасибо за чтение

Ответы [ 3 ]

3 голосов
/ 21 марта 2019

В функции main () я хочу вызвать метод1, а не метод2.Как мне этого добиться?Спасибо за чтение

И это именно то, что вы называете

obj.GetVal(false)

, потому что false - это bool, так что это точное соответствие для метода не-шаблона.И когда вызов соответствует методу шаблона и методу, не являющемуся шаблоном, метод не-шаблона (в случае совпадения точный ) предпочтителен.

Настоящая проблема заключается в следующем: как вызватьmethod2 вызывает его с типом (bool) не шаблонного метода (метод 1)?

Ответ (возможный ответ): добавить template, вызывая его

obj.template GetVal(false)

Ниже приведен полный рабочий пример

#include <iostream>

struct A
 {
   //Lets call this method 1
   int GetVal (bool)
    { return 1; }

   //Lets call this method 2
   template <typename T>
   int GetVal (T)
    { return 2; }
 };

int main ()
 {
   A obj;

   std::cout << obj.GetVal(false) << std::endl;           // print 1
   std::cout << obj.template GetVal(false) << std::endl;  // print 2
 }

- РЕДАКТИРОВАТЬ -

Учитывая, что ОП точно указывает, что метод 1 равен const (иметод 2 - нет), метод 2 стал лучше.

Проблема может быть решена путем изменения A, как в ответе Jarod42 (добавление неконстантного не шаблонного метода, который вызывает метод const или SFINAE).отключение метода шаблона 2, когда T равен bool) или как в ответе Wanderer (делая const также метод 2).

Но если вы этого не сделаете (или если вы не можете)изменить класс A, вы можете просто использовать static_assert() непосредственно в main()

std::cout << static_cast<A const &>(obj).GetVal(false) << std::endl;
1 голос
/ 21 марта 2019

Я знаю только 2 варианта

  1. Используйте все перегрузки как постоянные

    //Lets call this method 1
    int GetVal(bool isCondition) const
    { /*do something and return val*/ }
    
    //Lets call this method 2
    template<typename T>
    int GetVal(T expression) const
    { /*do something using expression and return val*/ }
    
  2. или как неконстантный

    //Lets call this method 1
    int GetVal(bool isCondition)
    { /*do something and return val*/ }
    
    //Lets call this method 2
    template<typename T>
    int GetVal(T expression)
    { /*do something using expression and return val*/ }
    

Тогда будет вызван метод 1

   std::cout << obj.GetVal(false) << std::endl;

Если вам нужен метод 1 const, используйте второй пример Jarod42. Это wokring

template <typename T, std::enable_if_t<!std::is_same<bool, T>::value> = 0 >
int GetVal(T expression)
{ /*do something using expression and return val*/ }
1 голос
/ 21 марта 2019

Вы можете добавить дополнительную перегрузку:

class A{
public:
    // Lets call this method 1
    int GetVal(bool isCondition) const { /* do something and return val */ }
    int GetVal(bool b) { return static_cast<const A&>(*this).GetVal(); }

    // Lets call this method 2
    template<typename T>
    int GetVal(T expression) { /* do something using expression and return val */ }}
};

Или используйте SFINAE для method2, чтобы отбросить bool параметр:

class A{
public:
    // Lets call this method 1
    int GetVal(bool isCondition) const { /* do something and return val */ }

    // Lets call this method 2
    template <typename T, std::enable_if_t<!std::is_same<bool, T>::value>, int> = 0>
    int GetVal(T expression) { /* do something using expression and return val */ }}
};
...