模板化类型的 ADL 和友元函数

ADL and friend functions of templated types

我正在尝试使用模板自动为我生成大量运算符。它们与以下代码非常相似,无法编译:

struct A
{
    int value = 1;
};

struct B
{
    int value = 2;
};  

template<typename ParamA, typename ParamB>
struct C
{
    C(int v) : value(v) {}
    
    friend C operator+(const ParamA& a, const ParamB& b)
    {
        return C(a.value + b.value);
    }
    
    int value;
};

int main()
{
    C<A, B> c = A() + B();
}

错误:

 In function 'int main()':
26:21: error: no match for 'operator+' (operand types are 'A' and 'B')
26:13: warning: unused variable 'c' [-Wunused-variable]

为什么 Argument Dependent Lookup 找不到 A 和 B 的运算符 +?我想这可能是因为它既不在全局命名空间中,也不在与 A 或 B 相同的命名空间中,但我不确定如何解决这个问题。

有人知道我在这里尝试做的事情是否可行吗?

像这样的东西会起作用:

// Struct definitions for A & B ...

struct C
{
    C(int v) : value(v) {}    
    int value;
};

template <typename ParamA, typename ParamB>
C operator+(const ParamA& a, const ParamB& b)
{
        return C(a.value + b.value);
}

我从 C 结构中删除了友元声明,因为它是不必要的。或者,您可以在 AB 类 内进行友元运算符声明,尽管这可能不是您想要的。

struct C;

struct A
{
    int value = 1;

    template <typename paramA, typename paramB>
    friend C operator+(paramA a, paramB b);
};

struct B
{
    int value = 2;
    template <typename paramA, typename paramB>
    friend C operator+(paramA a, paramB b);
};  

// Struct definition for C
...
// Define templated operator+ function
...

如@Dani 所述,将 operator+ 定义为完全通用并不理想。如果只有类型 A 和 B 需要运算符,则不需要模板。如果没有,那么有一些方法可以限制类型。