Подтвердить что ты не робот

Как принудительно вызвать перегрузку функции с константой?

Я пытаюсь вызвать функцию const внутри класса, но существует функция non const с тем же именем.

Примечание. Я не могу просто изменить имена.

class MyQuestion
{
 void fun()
 {
   cout<<"a"; 
 }

 void fun()const
 { 
   cout<<"b"; 
 }

 void call()
 {
   fun();//<how to call fun() const?
 }
};
4b9b3361

Ответ 1

Вариант №1:

Вызвать эту функцию с помощью указателя на const квалифицированный тип:

void call()
{
    static_cast<const MyQuestion*>(this)->fun();
    //          ~~~~^
}

Вариант № 2:

Сделать вызывающую функцию a const -qualified одним:

void call() const
//          ~~~~^
{
    fun();
}

Ответ 2

Вы должны вызвать функцию на указателе const. Для этого я рекомендую создать локальную переменную-указатель:

const auto *c = this;
c->fun();   // calls fun() const

fun();      // calls fun()

Живая демонстрация


Если вам это нужно часто и/или если вы не хотите использовать локальную переменную, вы также можете ввести частную вспомогательную функцию, которая возвращает const this указатель:

const MyQuestion *const_this() const {
    return this;
}

а затем вызовите fun следующим образом:

const_this()->fun();   // calls fun() const

fun();                 // calls fun()

Демо-версия


Еще один вариант - написать функцию make_const, которая выполняет приведение к указателю const без необходимости упоминать имя класса (это в основном a static_cast для указателя const выведенного типа):

template <typename T>
const T* make_const(T *ptr) {
    return ptr;
}

а затем вызовите fun следующим образом:

make_const(this)->fun();    // calls fun() const

fun();                      // calls fun()

Демо-версия


Для аргумента (я не рекомендую следующий), в сочетании с предложением выше, вы также можете ввести глобальный макрос, который расширяется до make_const(this):

#define  const_this  make_const(this)

а затем вызовите fun следующим образом:

const_this->fun();   // calls fun() const

fun();               // calls fun()

Живая демонстрация

Ответ 3

Я хотел бы добавить еще одно возможное решение для уже отличных.

Вы можете помочь компилятору выбрать правильную перегрузку с помощью указателя функции с ожидаемой сигнатурой:

// Pointer to the version of fun with const
void (MyQuestion::*f)()const = &MyQuestion::fun;
(this->*f)(); // This would call the const fun

Смотрите демо здесь или полный код ниже:

struct MyQuestion
{
    void fun()
    {
        std::cout<<"a"; 
    }

    void fun()const
    { 
        std::cout<<"b"; 
    }

    void call()
    {
        void (MyQuestion::*f)()const = &MyQuestion::fun;
        (this->*f)();
    }
};

Почему это работает?

Ну, тип указателя f равен void (MyQuestion::*)()const, который совпадает с MyQuestion::foo()const, но не совпадает с MyQuestion::foo(), поэтому, когда вы берете адрес электронной почты функции &MyQuestion::fun, указатель f > может указывать только на версию const.

Ответ 4

как насчет перегрузки call(). Следующее выполнение выполняет эту работу. Я предполагаю, что это то, что вы хотите реализовать.

#include <iostream>
using namespace std;

class A
{
public:
    void fun() { cout << "non" << endl; }
    void fun() const { cout << "const" << endl; }

    void call() { fun(); }
    void call() const { fun(); }
};

int main()
{
    A a;
    a.call();

    const A b;
    b.call();
    return 0;
}