2015-11-02 1 views
2

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

import std.stdio; 
struct A 
{ 
    this (int arg = 1) { 
     writeln("Correct constructor"); 
    } 

    this(); 
} 

Как использовать значение по умолчанию конструктора?

void main() 
{ 
      A a = A(); 
} 

... производит Error: constructor app.A.this is not callable because it is annotated with @disable. Если я удалю атрибут @disable из конструктора по умолчанию, я бы не получил свой собственный конструктор.

И почему структурам не разрешено иметь настраиваемый конструктор по умолчанию?

ответ

2

Я не знаю, что сделка с STRUCT ctors, но вы могли бы обмануть и попытаться перегрузки статического opCall:

import std.stdio; 
struct A { 
    static auto opCall() { 
     writeln("Correct constructor"); 
     auto a = typeof(this).init; 
     return a; 
    }; 
}; 

void main() { 
    A a = A(); 
}; 
+0

Это похоже на работу. Насколько обманывает это? Должен ли я ожидать каких-либо побочных эффектов? Например. Я заметил, что, когда я заменяю строку main на 'A a = A.init', статический opCall не вызван, но это не проблема со мной. –

+0

@AdamRyczkowski: моя главная проблема заключалась в том, что с этим подходом не существует '.__ ctor', что может помешать некоторым методам интроспекции. Я, честно говоря, не очень много разбираюсь в «статическом opCall», но я подозреваю, что он будет отлично работать для большинства случаев использования. – Cauterite

+0

Кроме того, как вы отметили, '.init' никогда не будет вызывать функцию, поскольку он компилируется в простой« mov »или« rep movs »(x86) для записи значений по умолчанию. – Cauterite

1

Вы не должны реализовать конструктор по умолчанию STRUCT (вот почему: Why can I not implement default constructors for structs in D?).

Удалите строку this(); в своем коде. Тебе это не нужно.

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

import std.stdio; 

struct A { 
    int a; 
    int b; 

    this (int arg = 1) { 
    a = arg; 
    // writeln("Correct constructor"); 
    } 

} 

immutable(A) defA = A(5); 

void main() { 
    A a1 = A(2); 
    writeln(a1); // output: A(2, 0) 

    // Or, init all to defaults 
    A a2 = A.init; 
    writeln(a2); // output: A(0, 0) 
    A a3 = A(); // same as A.init, as you can see 
    writeln(a3); // output: A(0, 0) 

    A a4 = defA; // Let's use our "default" value 
    a4.b = 10; 
    writeln(a4); // output: A(5, 10) 
} 
+0

Нет. Он вызывает «Правильный конструктор» только один раз, при втором вызове ('A a2 = A (2)'). Первый вызывает конструктор по умолчанию, который инициализирует все нулями и никогда не выполняет собственный код. –

+0

Первый - это инициализатор структуры. Я не сказал, что выполнит конструктор с параметром по умолчанию. Второй делает. Я отредактирую свой пост, чтобы избежать этого недоразумения. – DejanLekic