Вопрос

If I expect a template template parameter to have one arguement then I could declare it as follows:

template<template<typename> class T>
struct S {
    T<int> t_;
    //other code here
}

however if I later want to provide a template template parameter which takes two arguements where the second has a default value (like std::vector) T<int> t_; would still work but the template would not match template<typename> class T. I could fix this by making template<typename> class T into a variadic template template template<typename...> class T. Now my code is more flexible.

Should I make all my template template parameters variadic in future? Is there any reason I should not (assuming C++11 support is already required for my code for other reasons)?

Это было полезно?

Решение

First, documentation. If the parameter is variadic, the user now needs to check some other source to find out that this really wants something that will takes one template parameter.

Second, early checking. If you accidentally pass two arguments to T in S, the compiler won't tell you if it's variadic until a user actually tries to use it.

Third, error messages. If the user passes a template that actually needs two parameters, in the variadic version the compiler will give him an error message on the line where S instantiates T, with all the backtrace stuff in-between. In the fixed version, he gets the error where he instantiates S.

Fourth, it's not necessary, because template aliases can work around the issue too.

S<vector> s; // doesn't work
// but this does:
template <typename T> using vector1 = vector<T>;
S<vector1> s;

So my conclusion is, don't make things variadic. You don't actually gain flexibility, you just reduce the amount of code the user has to write a bit, at the cost of poorer readability.

Другие советы

If you know already that you will need it with high probability, you should add it. Otherwise, You Ain't Gonna Need It (YAGNI) so it would add more stuff to maintain. It's similar to the decision to have a template parameter in the first place. Especially in a TDD type of environment, you would refactor only when the need arises, rather than do premature abstraction.

Nor is it a good idea to apply rampant abstraction to every part of the application. Rather, it requires a dedication on the part of the developers to apply abstraction only to those parts of the program that exhibit frequent change. Resisting premature abstraction is as important as abstraction itself

Robert C. Martin Page 132, Agile Principles, Patterns and Practices in C#

The benefits of variadic templates can be real, as you point out yourself. But as long as the need for them is still speculative, I wouldn't add them.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top