2016-06-15 5 views
5

Я определил классИмея шаблонный параметр зависит от списка параметров

template <typename... Ts> struct Bar { 
    using inner_type = /* whatever */; 
}; 

Теперь, мне нужно определить шаблонный класс Foo, параметры шаблона некоторые параметры пакета, а значение типа Bar::inner_type экземпляра для этот пакет параметров. К сожалению, я не могу это сделать. Если я определяю это так:

template <Bar<Ts...>::inner_type SomeValue, typename... Ts> struct Foo { }; 

компилятор не распознает Ts, когда он используется, так как он не видит пакет параметров еще; но если я определяю это так:

template <typename... Ts, Bar<Ts...>::inner_type SomeValue> struct Foo { }; 

компилятор глумится моей попытке использовать параметр пакета перед другими параметрами шаблона.

Итак, как я могу это сделать?

Примечание: В случае, если это имеет значение, это не помогло мне с GCC 4.9.3.

+0

параметр шаблона не типа (например, '' шаблон )? – bolov

+0

Не можете ли вы использовать 'template struct Foo;'? – Jarod42

+2

Лучше всего было бы показать нам, как вы собираетесь создавать экземпляр Foo – bolov

ответ

2

Вы можете частично специализировать свою-структуру:

template<typename...> 
struct Bar { using inner_type = int; }; 

template <typename T, typename T::inner_type T> 
struct Foo; 

template <typename... Ts, typename Bar<Ts...>::inner_type SomeValue> 
struct Foo<Bar<Ts...>, SomeValue> { }; 

int main() { 
    Foo<Bar<int>, 3> foo; 
} 

Этого способ Ts параметра пакета выведенные и Foo ожидает, что второй параметр шаблона, чтобы быть типа Bar<Ts...>::inner_type.

+0

Это не должно компилироваться ... у него есть пакет параметров перед другим параметром шаблона. – einpoklum

+2

@einpoklum Выводится по специализации, это законно. Он действительно компилируется. :-) – skypjack

+1

О да. Это здорово, спасибо. – einpoklum

0

это разрешает проблему?

#include <type_traits> 

using namespace std; 

template <typename... Ts> class Bar { 
public: 
    using inner_type = int; 
}; 

template <typename... Ts> class Foo { 
    using bar_inner_type = typename Bar<Ts...>::inner_type; 
    static_assert(is_same<int, bar_inner_type>::value,""); 
}; 
+0

Нет, см. Править. Мне нужно значение, а не тип. – einpoklum

1

Самое лучшее, что я мог придумать:

template <class Inner, Inner Val, class... Args> 
struct Foo { 
    static_assert(std::is_same<Inner, typename Bar<Args...>::inner_type>::value, "Wrong type"); 
}; 

Вы должны явно назвать тип.

+0

Это то, что я делал в качестве обходного пути. (На самом деле в моем случае я не беспокоюсь о статическом утверждении, так как я использую это значение как аргумент функции, которая нуждается в «Bar <...> :: inner_type»). Я мог бы принять это, но я не могу его продвинуть, так как мне это не нравится ...: -P – einpoklum

0

Если я правильно понял вашу проблему, вы можете сделать что-то вроде этого:

template <typename... Ts> struct Bar { 
    using inner_type = /* whatever */; 
}; 

template <typename... Ts> struct Foo { 
    using inner_type = typename Bar<Ts...>::inner_type; 
}; 
+0

Нет, ты этого не сделал. Мне нужно передать значение как параметр шаблона, а не тип. См. Принятый ответ. – einpoklum

Смежные вопросы