LINUX.ORG.RU

История изменений

Исправление Cheater, (текущая версия) :

Хорошо, студентка. А ты как опытный сеньор С++ можешь объяснить студентке, как узнать присутствует ли в типе Т метод с данным именем и сигнатурой?

Ну, напиши соотствующий код, скомпилируется, значит есть.

Не всё так просто, решение «скомпилируется = есть метод» может дать ложно-положительный результат из-за приведения типов.

struct A {
    void foo(int);
    void foo(int, int);
};

int main()
{
    A().foo(float(1), float(2));

    return 0;
}
$ g++ -c foo.cpp && echo MATCHES
MATCHES       # oops

Моё решение: объявить переменную вида pointer-to-member с данной сигнатурой и попытаться её инициализировать.

struct A {
    void foo(int);
    void foo(int, char);
};

int main()
{
    void (A::*x)(float) = &A::foo;      // не компилируется
    void (A::*x)(int, int) = &A::foo;   // не компилируется
    void (A::*x)(int, char) = &A::foo;  // ок

    return 0;
}

Исправление Cheater, :

Хорошо, студентка. А ты как опытный сеньор С++ можешь объяснить студентке, как узнать присутствует ли в типе Т метод с данным именем и сигнатурой?

Ну, напиши соотствующий код, скомпилируется, значит есть.

Не всё так просто, решение «скомпилируется = есть метод» может дать ложно-положительный результат из-за приведения типов.

struct A
{
    void foo(int);
    void foo(int, int);
};

int main()
{
    A().foo(float(1), float(2));

    return 0;
}
$ g++ -c foo.cpp && echo MATCHES
MATCHES       # oops

Моё решение: объявить переменную вида pointer-to-member с данной сигнатурой и попытаться её инициализировать.

#include <iostream>

struct A {
    void foo(int);
    void foo(int, char);
};

int main()
{
    void (A::*x)(float) = &A::foo;      // не компилируется
    void (A::*x)(int, int) = &A::foo;   // не компилируется
    void (A::*x)(int, char) = &A::foo;  // ок

    return 0;
}

Исходная версия Cheater, :

Не всё так просто, решение «скомпилируется = есть метод» может дать ложно-положительный результат из-за приведения типов.

struct A
{
    void foo(int);
    void foo(int, int);
};

int main()
{
    A().foo(float(1), float(2));

    return 0;
}
$ g++ -c foo.cpp && echo MATCHES
MATCHES       # oops

Моё решение: объявить переменную вида pointer-to-member с данной сигнатурой и попытаться её инициализировать.

#include <iostream>

struct A {
    void foo(int);
    void foo(int, char);
};

int main()
{
    void (A::*x)(float) = &A::foo;      // не компилируется
    void (A::*x)(int, int) = &A::foo;   // не компилируется
    void (A::*x)(int, char) = &A::foo;  // ок

    return 0;
}