Why does the following code yield the compiler error no template named 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;
}
I've created a live demo of the code. It's working when I move the definition of make_static_vector
outside the class and leave only the declaration part inside the class.
Why is it not possible to define the function directly inside the class?
The only place you declare the template function is inside the class; it is not "visible" in the enclosing namespace and hence not available for normal lookup, only for argument dependent lookup.
You need to declare (and define) it outside the class for the function to be found, and to declare it as a friend function (as you noted).
From cppreference
A name first declared in a friend declaration within class or class template X becomes a member of the innermost enclosing namespace of X, but is not accessible for lookup (except argument-dependent lookup that considers X) unless a matching declaration at the namespace scope is provided...