#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. да, я решил выбрать этот вариант, хотя у меня нет абсолютно никаких причин использовать шаблоны здесь