2009-10-29 2 views
3

Этот класс:Как я могу иметь необязательный конструктор по умолчанию?

template <class T> 
struct A { 
    A() : t(T()) { 
    } 

    A(const T& t_) : t(t_) { 
    } 

    T t; 
}; 

не будет компилироваться, если T не имеет конструктора по умолчанию. Это одна:

template <class T> 
struct A { 
    A(const T& t_) : t(t_) { 
    } 

    T t; 
}; 

не будет иметь конструктор по умолчанию, даже если T имеет конструктор по умолчанию.

Я хочу иметь оба - Если нет T(), я не хочу A().

Я знаю, что SFINAE необходимо использовать. И что Boost.traits и Boost.enable_if могут помочь, но я не могу заставить его работать. Может ли кто-нибудь дать мне пример этого простого случая?

+0

что вы хотите(), чтобы вызвать на Т, если Т не имеет конструктора не по умолчанию? – Mark

+0

Если нет T(), я не хочу A() вообще. –

+4

Возможно, я ошибаюсь, но вы уверены, что первый из них не сработает, * если вы не пытаетесь использовать версию по умолчанию с T, у которой нет конструктора по умолчанию *? Оба GCC и Comeau в порядке с ним. Как вы создаете экземпляр класса? – UncleBens

ответ

0

Попробуйте это:

template <class T> 
struct A { 
    A(const T& t_ = T()) : t(t_) { 
    } 

    T t; 
}; 
1

функции-члены шаблонов классов инстанцируются только если вы вызываете их. Если вы никогда не вызывать A::A(), то код вызова T::T() не должен быть собран в этом коде:

template <class T> 
struct A { 
    A() : t(T()) { 
    } 
    // ... 
}; 

У вас возникли проблемы с этим? Если да, то какой компилятор вы используете?

Тем не менее, если код с помощью A вызывает его конструктор по умолчанию, то единственный выход я вижу, чтобы переместить создание T в A::A() в некоторые черты класса:

template< typename T > 
struct default_a_ traits { 
    static T default_construct() 
    { 
    return T(); 
    } 
}; 

template <class T, class Traits = default_a_traits<T> > 
struct A { 
    A() : t(Traits::default_construct()) { 
    } 
    // ... 
}; 

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

struct my_special_traits_for_b { 
    static T default_construct() 
    { 
    return read_b_from_db(); 
    } 
}; 

typedef A<B, special_traits_for_b> AB;