c как создать конструктор для типа typedef

#c #typedef

#c #typedef

Вопрос:

В моем проекте на c у меня есть тип с именем Expression

 typedef std::function<uint64_t(uint64_t)> Expression;
 

У меня также есть функция, которая действует как конструктор

 Expression ExpressionConstructor(std::string Expr, MicroCodeDescriptor* descriptor) {
//implementation doesn't matter in this case
}
 

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

 Expression expr= ExpressionConstructor(code, descriptor);
 

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

Комментарии:

1. ExpressionConstructor похоже на заводскую функцию, за исключением того, что у нее нечетное имя. В чем причина, по которой вы не хотите использовать фабричную функцию и нуждаетесь в чем-то, что ведет себя как конструктор ?.

2. Конструкторы не имеют никакого возвращаемого типа. Конструкторы и деструкторы — это «специальные» функции, которые не имеют имен, ничего не возвращают и не могут быть вызваны.

3. @GideonMax Стандарт (см. [special] Раздел.) очень четко говорит об этом: «Конструкторы не имеют имен». (таким образом, вы не можете ссылаться на него для вызовов или чего-либо еще) и «Конструктор используется для инициализации объектов своего типа класса». (Таким образом, он не создает объект, а тем более не возвращает его.) Компилятор, конечно, может ссылаться на конструктор и вызывать его, но вы не можете, и то, какое имя использует компилятор и как оно вызывается, совершенно не имеет отношения к деталям реализации.

4. @molbdnilo 1. конструктор получает адрес, который будет использоваться для объекта, И возвращает его, дизассемблирование не врет. 2. « CodeTreePart part(str); CodeTreePart part=CodeTreePart::CodeTreePart(str); « эти две строки кода (почти) эквивалентны и являются действительными и работают (я проверил это) не уверен, что вы имеете в виду, но реальный мир не согласен, вы уверенывы не читаете старый стандарт c ? ps. разница между строками заключается в том, что вторая инициализирует, а затем присваивает, первая просто инициализирует

5. @GideonMax, как знает любой не новичок, CodeTreePart part=CodeTreePart::CodeTreePart(str); не является присваиванием (и я понятия не имею, какую точку зрения вы пытаетесь показать в этом примере). И вы не можете определить семантику языка, изучая сгенерированный код.

Ответ №1:

A typedef не является новым типом, он просто создает псевдоним, ваш Expression по-прежнему остается типом std::function<uint64_t(uint64_t)> .

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

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

Ответ №2:

Вместо typedef вашего выражения может быть класс, производный от std::function<uint64_t(uint64_t)> . Затем вы можете определить его конструктор (ы), деструктор и вызвать его как std::function :

 struct Expression : public std::function<uint64_t(uint64_t)>
{
    Expression(std::string Expr, MicroCodeDescriptor* descriptor)
    {

    }
};

Expression e = Expression("", nullptr);
uint64_t res = e(123);
 

Или даже лучше сделать его шаблоном:

 template<typename R = uint64_t, typename T = uint64_t>
struct Expression : public std::function<R(T)>
...
 

Комментарии:

1. да, я решил выбрать этот вариант, хотя у меня нет абсолютно никаких причин использовать шаблоны здесь