Из template class шаблон. метод без парам. другого class
От: Ruzzz  
Дата: 03.04.17 20:34
Оценка:
Код работает для 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

Вопрос: а как это называется официально? Что это за правило в С++?
Отредактировано 03.04.2017 20:36 Ruzzz . Предыдущая версия .
Re: Из template class шаблон. метод без парам. другого class
От: swingus  
Дата: 04.04.17 06:52
Оценка:
e зависит от параметра шаблона, поэтому next() может быть шаблонной или нет в зависимости от конкретного типа. Здесь короткое объяснение и ссылка на книгу, которую легко найти, гдё всё чётко, по-пацански распедалено. Кстати, если бы это была бы не функция, а оператор (), то VC++ до 2015 U3 включительно настаивал, чтобы слова template не было. Исправленно это только в 2017.

Здравствуйте, Ruzzz, Вы писали:

R>Вопрос: а как это называется официально? Что это за правило в С++?
Отредактировано 04.04.2017 6:56 swingus . Предыдущая версия .
Re: Из template class шаблон. метод без парам. другого class
От: rg45 СССР  
Дата: 04.04.17 07:19
Оценка: 2 (1) +1
Здравствуйте, 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 ]

--
Не можешь достичь желаемого — пожелай достигнутого.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.