2016-12-25 3 views
-1
void foo(); 
class Foomatic() { 
    void bar(); 
    void baz() 
    { 
     std::thread a(foo); // this compiles 
     std::thread b(Foomatic::bar, this); // this doesn't 
     std::thread c(&Foomatic::bar, this); // and this compiles 
     // ... 
    } 
}; 

Я знаю, что правильный синтаксис для указателя на функцию-член равен &Foomatic::bar.Указатель на функцию-член - синтаксис

Но зачем именно Foomatic::bar? Что возвращается? И почему именно &Foomatic::bar правильный? Это кажется мне интригующим.

Это не дубликат. Вопрос, на который вы ссылаетесь, отвечает правильному синтаксису, а не объясняет причины.

Я спрашиваю, почему C++ здесь настолько непоследователен, я уже знаю, что такое синтаксис.

+0

@Ed Heal: Это не дубликат. Я не спрашиваю, каков правильный синтаксис, потому что я знаю, что это такое, но ** почему ** правильный правильный синтаксис. Ответы только говорят, что такое правильный синтаксис. – marmistrz

+3

Ответ тавтологический. Синтаксис неверен, потому что спецификация языка так говорит. Почему футбольный матч длится 90 минут? Потому что это то, что говорят правила. –

+3

Возможно, реальный вопрос заключается в том, почему 'a (foo)' работает, когда это должно быть 'a (& foo)'? –

ответ

4

C++ унаследовал преобразование из функций в указатели на функции из C: в C вы могли просто назначить имя функции указателю функции без необходимости принимать адрес. Этот «распад» названий функций на указатели функций кажется несколько необоснованным и вызывал некоторую путаницу в C.

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

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

Семантически, что-то вроде T::member является ссылкой на элемент, а не на указатель на элемент. Однако, я не думаю, что можно сформулировать этот тип с текущей спецификацией. Возможно, будущий стандарт определяет someting для этого синтаксиса.

0

Если &Foomatic::Bar функция указателя на член (потому что вы принимаете адрес функции, используя адрес-оператора &), то Foomatic::Bar функция члена, а не указатель на - функция члена.

Это то же самое с функциями, отличными от членов: если &foo является указателем на функцию (не являющейся членом), то foo является функцией.

Ни C++, ни C не имеют функций как объектов первого класса, например, вы не можете иметь переменную, тип/значение которой является функцией - только указатель на нее.

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