2013-09-04 5 views
0

таргетирования Visual Studio C++ 2008параметры шаблона Набор по умолчанию из внутреннего класса шаблона с использованием параметров шаблона внешнего класса

Ситуация: у меня есть класс шаблона с большим количеством параметров, многие со значениями по умолчанию.

template <typename A, typename B = b, typename C = c> 
struct Outer 
{ 
    typedef typename A typeA; 
    typedef typename B typeB; 
    typedef typename C typeC; 
}; 

Так хорошо пока. Теперь у меня есть определенный пользователем тип, состоящий из лотов и лотов Outer. В этой ситуации известны типы A и B, C - нет.

Мой первый подход, связанный с этим, состоял в том, чтобы повторить A и B в новом типе пользователя.

template<typename A, typename B> 
struct UserDefinedType { 
    Outer<A, B, int> AnIntOuter; 
    Outer<A, B, float> AFloatOuter; 
}; 

Это работает, но довольно скучно. (а также другие сложности от реального кода). Я думал ... почему бы не создать новый внутренний класс с использованием параметров шаблона, который был принят в качестве значения по умолчанию, так что я пытался сделать это:

template<typename A, typename B> 
struct AnotherUserDefinedType { 
    template<typename CC, typename AA = A, typename BB = B> 
    struct Inner : public Outer<AA, BB, CC> {}; 

    Inner<int> AnIntInner; 
    Inner<float> AFloatInner; 
}; 

При попытке компиляции это, я получаю «слишком мало шаблонные аргументы, которые, как представляется, привязаны к объявлению участника (AnIntInner в этом случае).

Что я хочу знать: Является ли это (используя параметры шаблона внешнего класса как параметры шаблона по умолчанию для внутреннего класса) даже удаленно?

Если это IS возможно, это мое строительство неправильно или есть известные проблемы с MSVC++ 2008? Или, если, конечно, я, наверное, есть что-то еще неправильно в моем коде, а

UPDATE

Ааа, помогал 20/20 задним числом всегда велик. Я вижу, что у меня есть хотя бы хет-трик вопросов с моим вопросом и ответ, который мне действительно нужен.

Во-первых, @DyP был прав, вызывая для SSCCE, хотя я просто отсутствовал пять строк для полного примера (один, если я входил в запутанный конкурс C++). Я посмотрел на свой код и сказал: «Это выглядит правильно, поэтому нужно, чтобы новая вещь, которую я пробовала, вызывала проблемы », и я даже не построил свой собственный пример. Мне нужно поработать над моим компилятором, выпущенным шаблоном, сообщение об ошибке, интерпретирующее-fu (о, да, и вспомогательная часть ...).

Однако, поскольку @nickie вежливо не говорит, что конструкция избыточна. Параметры шаблона по умолчанию имеют свое место, но здесь его даже не нужно. Внутренний класс имеет видимость параметров шаблона, используемых во внешнем классе. Лучше всего только настроить параметры, которые мне нужны, чтобы быть «свободными». Я думаю, @nickie ответил на вопрос, даже если технически я был не ошибаюсь в первую очередь, поэтому ответ @ nickie получает галочку.

Это не конец. @DyP правильно интуитивно поняла мою реальную проблему, которая заключается в том, что я хотел заархивировать некоторые параметры шаблона (повторное копирование параметров внешнего шаблона здесь имеет свои применения, где мы хотим, чтобы опция изменения параметра шаблона, а не жестко привязывала его к реальному currying (ну, параметр curries может быть функтором ... но я отвлекся)). Мне просто нужен тип, а не расширять класс. Проблема с наследованием заключается в том, что он прерывает некоторые переопределения, а именно operator =().

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

template<typename A, typename B> 
struct FinalUserDefinedType { 
    template<typename C, typename AWithDefault = A> 
    struct CurryType { 
     typedef Outer<AWithDefault, B, C> type; 
    }; 

    CurryType<int>::type AnIntOuter; 
    CurryType<float>::type AFloatOuter; 
    CurryType<double, int>::type AnOverriddenDefault; 
}; 

UPDATE 2

обмани меня однажды, позор на ME, обмани меня дважды, отправьте меня в девятый круг.

Еще раз, я не скомпилировал пример, который я дал. Eliding от моего реального кода (@DyP поймал это еще раз ...), пример должен быть:

template<typename A, typename B> 
struct FinalUserDefinedType { 
    template<typename C, typename AWithDefault = A> 
    struct CurryType { 
     typedef Outer<AWithDefault, B, C> type; 
    }; 

    typename CurryType<int>::type AnIntOuter; 
    typename CurryType<float>::type AFloatOuter; 
    typename CurryType<double, int>::type AnOverriddenDefault; 
}; 

Для виртуальных бонусных очков, можно объявить AnIntOuter, и др без использования typename?

+0

'ЬурейеЕ TYPENAME A TypeA,' 'не typename' здесь, пожалуйста. (см. [этот вопрос] (http://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-the-template-and-typename-keywords)) – dyp

+0

Просьба предоставить [SSCCE] (http://sscce.org). [Этот пример] (http://ideone.com/oOIsi6) отлично компилируется на VS2008. – dyp

+0

Btw: вам не нужно наследовать от 'Outer', вы также можете использовать typedef:' template struct Inner {typedef Outer type; }; 'и then' typename Inner :: type AnIntInner; ' – dyp

ответ

3

Я не думаю, что это правильный способ сделать то, что вы хотите (если я понял, что это правильно):

template <typename A, typename B = b, typename C = c> 
struct Outer 
{ 
    typedef A typeA; 
    typedef B typeB; 
    typedef C typeC; 
}; 

template<typename A, typename B> 
struct AnotherUserDefinedType { 
    template<typename C> 
    struct Inner : public Outer<A, B, C> {}; 

    Inner<int> AnIntInner; 
    Inner<float> AFloatInner; 
}; 
Смежные вопросы