Код работает для vc++ в любом случае, а g++ требует указать ключевое слово template, см. комментарий в коде:
#include <iostream>
template <typename ResultInt>
class CalcFor
{
public:
CalcFor() : total_(0) { }
template <typename T>
void next()
{
total_ += sizeof(T);
}
ResultInt total() const { return total_; }
private:
ResultInt total_;
};
template <typename ResultInt, typename... Ts>
class Calc
{
public:
ResultInt total() const
{
CalcFor<ResultInt> e;
int dummy[] = { (e.template next<Ts>(), 0)... }; // Если e.next<Ts>() - g++ выдает ошибку
(void)dummy;
return e.total();
}
};
int main(const int /* argc */, const char* const* /* argv */ )
{
Calc<size_t, int, char> c;
std::cout << c.total() << '\n';
return 0;
}
Вот тут можно запустить
http://ideone.com/BGXBds
g++ ошибка:
/contest/contest.cpp: In member function 'ResultInt Calc<ResultInt, Ts>::total() const':
/contest/contest.cpp:204:35: error: expected primary-expression before '>' token
int dummy[] = { (e.next<Ts>(), 0)... };
^
/contest/contest.cpp:204:37: error: expected primary-expression before ')' token
int dummy[] = { (e.next<Ts>(), 0)... };
^
/contest/contest.cpp:204:42: error: expansion pattern '(((e.next < <expression error>) > <expression error>), 0)' contains no argument packs
int dummy[] = { (e.next<Ts>(), 0)... };
^~~
Прочитал об этом тут
http://ldmitrieva.blogspot.com/2010/11/blog-post.html
Вопрос: а как это называется официально? Что это за правило в С++?
e зависит от параметра шаблона, поэтому next() может быть шаблонной или нет в зависимости от конкретного типа.
Здесь короткое объяснение и ссылка на книгу, которую легко найти, гдё всё чётко, по-пацански распедалено. Кстати, если бы это была бы не функция, а оператор (), то VC++ до 2015 U3 включительно настаивал, чтобы слова template не было. Исправленно это только в 2017.
Здравствуйте, Ruzzz, Вы писали:
R>Вопрос: а как это называется официально? Что это за правило в С++?
Здравствуйте, Ruzzz, Вы писали:
R>Код работает для vc++ в любом случае, а g++ требует указать ключевое слово template, см. комментарий в коде:
R>...
Таково требование стандарта языка:
14.2/4 (ISO/IEC 14882)
When the name of a member template specialization appears after . or -> in a postfix-expression or after a nested-name-specifier in a qualified-id, and the object expression of the postfix-expression is type-dependent or the nested-name-specifier in the qualified-id refers to a dependent type, but the name is not a member of the current instantiation (14.6.2.1), the member template name must be prefixed by the keyword template. Otherwise the name is assumed to name a non-template. [ Example:
struct X {
template<std::size_t> X* alloc();
template<std::size_t> static X* adjust();
};
template<class T> void f(T* p) {
T* p1 = p->alloc<200>(); // ill-formed: < means less than
T* p2 = p->template alloc<200>(); // OK: < starts template argument list
T::adjust<100>(); // ill-formed: < means less than
T::template adjust<100>(); // OK: < starts template argument list
}
—end example ]