c++ - 模板类中的友元函数

标签 c++ templates friend

我试图让乘法运算符成为名为 TVector3 的模板类的友元。我读过我可以在类声明中声明友元函数之前对其进行前向声明,但是我这样做的尝试是徒劳的。我知道我可以简单地定义友元函数而不是声明它,但我希望它使用前向声明技术。

特别是我试图实现 this我的案例的解决方案。我找到了 this David Rodriguez 也发布了解决方案(第三版),但我不知道我做错了什么。

我使用“g++ template.cpp tempmain.cpp a”进行编译,编译器 (g++) 出现以下错误:

对“ray::TVector3 ray::operator*(float, ray::TVector3 const&)”的 undefined reference

对于以下代码:

模板.h:

#ifndef TVECTOR_H
#define TVECTOR_H

#include <cmath>

namespace ray
{
    //forward declarations
    template <class T> class TVector3;
    template <class T> TVector3<T> operator* (T, const TVector3<T> &);

    template <class T>
    class TVector3 {

        public:
            union {
                struct {
                    T x, y, z;
                };
                T xyz[3];
            };

        //function needed
        friend TVector3<T> operator*<T> (T, const TVector3<T> &);
    };

}

#endif

模板.cpp:

#include "template.h"

using namespace ray;

//friend operator function
template<class T> TVector3<T> operator * (T f, const TVector3<T> &v)
{
    return TVector3<T>(f * v.x, f * v.y, f * v.z);
}

//instantiate template of type float
template class TVector3<float>;

tempmain.cpp:

#include <iostream>
#include "template.h"

int main()
{
    ray::TVector3<float> v1, v2;

    v2.x = 3;
    v1 = 4.0f * v2; //this reports as undefined

    std::cout << v1.x << "\n";

    return 0;
}

这是完整的源代码。我做错了什么?

最佳答案

根据一般经验,模板应在标题中定义。如果在 cpp 文件中定义它们,则需要手动实例化模板。您正在为类模板执行此操作,但您没有实例化 operator* 模板。

template TVector3<T> operator*<T> (T, const TVector3<T> &);

此外,我建议不要使用模板化的 operator*,而是通过在类模板中声明和定义它来使用非模板自由函数:

template <class T>
class TVector3 {
//function needed
    friend TVector3<T> operator*(T f, const TVector3<T> & v) {
       return TVector3<T>(f * v.x, f * v.y, f * v.z);
    }
};

这具有自由函数(它允许对第一个参数进行转换)和模板(它将根据需要生成自由函数——即无需手动提供所有实现)以及有限的可见性(它只能通过 ADL 进行查找)

关于c++ - 模板类中的友元函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12187231/

相关文章:

c# - 在 C# 中实现好友(在 C++ 中可用)功能

c++ - 不指定内部类型的模板模板参数

c++ - 模板作为递归函数

c++ - 将许多函数声明为类的友元

c++ - 使用 getline 从文件读取的垃圾值

c++ - 这是存储 float 的二维动态数组的正确初始化吗?

c++ - 关于c++上模板推导的编译错误

某些类型的模板函数的 C++ 特殊实例,它本身就是模板类

c++ - 如何访问单独类中的私有(private)构造函数?

c++ - 为什么 C++ 允许将指向基对象的指针转换为派生类的指针