2016-01-12 2 views
1

Я пишу функцию, которая работает с типом с множеством аргументов шаблона. Например:Работа над классом со многими аргументами шаблона

template <typename A, typename B, typename C, int MinSize, int MaxSize> 
struct Foo { 
    // ... 
}; 

Моя функция может работать на любом Foo - я не забочусь о аргументах шаблона. Я могу написать шаблон функции, чтобы принять эти объекты:

template <typename A, typename B, typename C, int MinSize, int MaxSize> 
void do_work(const Foo<A, B, C, MinSize, MaxSize>& foo) { 
    // ... 
} 

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

Есть ли другой способ написать do_work, так что мне не нужно включать все аргументы шаблона Foo? Возможно, используя более общий шаблон и static_assert, чтобы убедиться, что я получаю Foo?

template <typename FooType> 
void do_work(const FooType& foo) { 
    // make sure foo is a 'Foo<...>' 
    static_assert(??) 
} 
+1

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

+0

Это тоже верный ответ. Мне просто интересно, есть ли какая-то черная магия TMP, которая может сделать эту ошибку немного легче диагностировать. – zmb

+1

Вы можете использовать SFINAE, чтобы проверить, если объект имеет правильный интерфейс, чтобы сделать вашу работу –

ответ

0

Я думаю, что static_assert() идея не плохая, на самом деле, потому что она делает предположение о природе foo явным. Вы статически утверждаете, что тип имеет статический логический элемент с именем is_foo, для которого установлено значение true.

static_assert(FooType::is_foo); 

И это возвращает истину, только если вы определяете

template <class C, ...> 
class Foo { 
public: 
    static bool const is_foo = true; 
} 
4

Как насчет VARIADIC шаблона:

template <typename ...Args> 
void do_work(const Foo<Args...>& foo) { /* ... */ } 

Вы не получите на отдельные аргументы шаблона легко, хотя, но, возможно, это помогает.

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