【问题标题】:Defining a templated friend function inside a template class在模板类中定义模板化友元函数
【发布时间】:2016-06-23 20:04:47
【问题描述】:

为什么下面的代码会产生编译器错误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;
}

我创建了一个live demo of the code。当我将make_static_vector 的定义移到类外并仅将声明部分保留在类内时,它就起作用了。

为什么不能直接在类内部定义函数?

【问题讨论】:

    标签: c++ templates c++14 friend c++17


    【解决方案1】:

    您声明模板函数的唯一位置是在类内部;它在封闭的命名空间中不“可见”,因此不能用于正常查找,仅用于参数相关查找。

    您需要在类外部声明(和定义)它才能找到该函数,并将其声明为友元函数(如您所述)。

    来自cppreference

    首先在类或类模板 X 中的友元声明中声明的名称成为 X 的最内层封闭命名空间的成员,但不能用于查找(除了考虑 X 的参数相关查找),除非在提供了命名空间范围...

    【讨论】:

    • “它在类外声明时有效”不是真的。违反 ODR 并不好玩。
    • @T.C.正如他在问题中指出的那样,我假设只有一个定义。我已经清除了。
    猜你喜欢
    • 2016-10-19
    • 2011-05-16
    • 1970-01-01
    • 2010-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-18
    相关资源
    最近更新 更多