Любой способ определить, реализует ли класс operator () - PullRequest
1 голос
/ 20 июня 2010

Я пытаюсь найти, есть ли способ проверить, является ли класс функционалом, потому что я хочу написать шаблон, который использует его?

Есть ли простой способ сделать это?Или я просто обертываю вещи в попытке / поймать?Или, возможно, компилятор даже не позволит мне сделать это?

Ответы [ 4 ]

4 голосов
/ 20 июня 2010

Если у вас есть шаблон функции, написанный следующим образом:

template <typename T>
void f(T x)
{  
    x();  
}  

, вы не сможете создать его экземпляр с любым типом, который не может быть вызван как функция без аргументов (например, тип класса, который перегружает1004 * без аргументов вызывается как функция, которая не принимает аргументов).Если вы попытаетесь это сделать, вы получите ошибку компиляции.

Это самый простой способ требовать, чтобы тип, для которого создается экземпляр шаблона, имел определенные свойства: просто полагайтесь на тип, имеющий эти свойства, когда вы пишетешаблон, и если тип не имеет одного из обязательных свойств, будет невозможно создать экземпляр шаблона с этим типом.

2 голосов
/ 20 июня 2010

Существует довольно много способов применения типа параметра к синтаксису вызова

  1. Тип: указатель или , ссылка на тип функции или
  2. Тип представляет собой тип класса , который имеет функцию преобразования в один из типов в 1. или имеет применимый оператор ( ) .

Текущий C ++ не может проверить на 2. , поэтому вы остаетесь без проверки, как объясняют другие ответы.

0 голосов
/ 20 июня 2010

Если вам действительно нужен тест, чтобы увидеть, реализует ли тип T оператор () некоторой заданной сигнатуры, вы можете использовать тот же трюк SFINAE, который использовался для идентификации существования любого другого члена класса, который здесь обсуждается: C ++подстановка шаблона «если тогда еще»

0 голосов
/ 20 июня 2010

Это подпадает под это и получит ошибку компиляции.Когда код скомпилирован, функция шаблона или классы шаблона расширяются для используемых типов, как если бы были дублированные копии этого кода шаблона, по одной для каждого типа.

Таким образом, вы можете делать все, что угодновсе типы, используемые для ваших шаблонов, поддерживают его, у вас нет проблем.Если они не поддерживают его, у вас есть ошибка компиляции, и вы не можете запустить свой код, не исправив его.

template <typename T>
void DoIt(T a)
{
    a.helloworld();//This will compile fine
    return a();//This will cause a compiling error if T is B
}

class A
{
public:
    void a.helloworld(){}
    void operator()(){}
};

class B
{
public:
    void a.helloworld(){}
};

int main(int argc, char**argv)
{
    A a;
    B b;
    DoIt(a);
    DoIt(b);//Compiling error

    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...