2016-03-09 6 views
3

Почему следующий код дает ошибку компилятора без шаблона с именем make_static_vector?Определение шаблона функции друга внутри класса шаблона

template<class Tuple> 
class vector; 

template<typename T, std::size_t N> 
using static_vector = vector<std::array<T, N>>; 

template<class Tuple> 
class vector 
{ 
private: 
    using value_type = std::decay_t<decltype(std::declval<Tuple&>().operator[](0))>; 

    template<typename T, typename... Elements> 
    friend static_vector<T, sizeof...(Elements)> make_static_vector(Elements&&... elements) { 
     return { std::forward<Elements>(elements)... }; 
    } 

    template<typename... Elements> 
    vector(Elements&&... elements) 
     : m_elements{ static_cast<value_type>(std::forward<Elements>(elements))... } 
    { } 

    Tuple m_elements; 
}; 

int main() 
{ 
    make_static_vector<double>(1, 1); 
    return 0; 
} 

Я создал a live demo of the code. Он работает, когда я перемещаю определение make_static_vector вне класса и оставляю только часть декларации внутри класса.

Почему невозможно определить функцию непосредственно внутри класса?

ответ

8

Единственное место, где вы объявляете функцию шаблона, находится внутри класса; он не «видим» в охватывающем пространстве имен и, следовательно, недоступен для обычного поиска, только для зависимого от аргумента поиска.

Вам нужно объявить (и определить) его вне класса для функции, которая будет найдена, и объявить ее как функцию друга (как вы отметили).

От cppreference

имени первого объявленного в другой декларации в пределах класса или шаблон класса X становится членом самих внутренних охватывающего пространства имен X, но не доступна для поиска (за исключением аргумента-зависимого поиска, что рассматривает X), если не указано сопоставление декларации в области пространства имен ...

+1

«это работает, когда объявлено вне класса», на самом деле. Нарушения ODR - это не весело. –

+0

@ T.C. Я предполагал, что будет только одно определение, как он отметил в вопросе. Я прояснил это. – Niall

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