模板朋友功能和返回类型推导

模板朋友功能和返回类型推导

本文介绍了模板朋友功能和返回类型推导的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意:这个问题确实与,但是我在那里找不到我的问题的答案。

Note: This question is really close to Return type deduction for in-class friend functions, but I did not find the answer to my problem there.

使用clang 3.4和std = c ++ 1y和clang 3.5进行了测试使用std = c ++ 14和std = c ++ 1z

Tested with clang 3.4 with std=c++1y and clang 3.5 with std=c++14 and std=c++1z

此代码可编译:

#include <iostream>

template<class T>
class MyClass {
    public:
        MyClass(T const& a) : impl(a) {}

        template<class T0, class T1> friend auto
        // requires operator+(T0,T1) exists
        operator+(MyClass<T0> const& a, MyClass<T1> const& b)
        {
            return MyClass<decltype(a.impl+b.impl)>{a.impl + b.impl};
        }

        T getImpl() const { return impl; }

    private:
        T impl;
};

int main() {
    MyClass<int> x(2);
    MyClass<long> y(2);

    auto z = x+y;
    std::cout << z.getImpl() << "\n";
}

现在,如果我在类外定义operator +,它将不再编译:

Now if I define operator+ outside of the class, it does not compile anymore:

template<class T>
class MyClass {
    public:
        MyClass(T const& a) : impl(a) {}

        template<class T0, class T1> friend auto
        operator+(MyClass<T0> const& a, MyClass<T1> const& b);

        T getImpl() const { return impl; }
    private:
        T impl;
};

template<class T0, class T1> auto
operator+(MyClass<T0> const& a, MyClass<T1> const& b)
{
    return MyClass<decltype(a.impl+b.impl)>{a.impl + b.impl};
}



C语3.4表示:

Clang 3.4 says:

error: use of overloaded operator '+' is ambiguous (with operand types MyClass<int> and MyClass<long>)

然后指出它认为是两个不同的功能:类中的声明和类外的定义。

And then points at what it believes to be two different functions: the declaration in the class and the definition outside the class.

我的问题是:这是一个clang错误,还是只是为一个朋友函数推导了模板参数,从而导致两个函数在某些情况下不相等?
还有什么建议:让operator +成为成员函数,或者在类内部定义朋友operator +(在我看来,这会使类的界面混乱)?

My question is: is it a clang bug, or just that template parameters are deduced for a friend function thus leading the two functions not being equivalent is some cases ?And what alternative would you suggest: make operator+ a member function, or define friend operator+ inside the class (which would in my opinion clutter the class interface) ?

仅供参考,我有一个这样的代码的真实用例,在这里我尝试包装第三方矩阵类,并且由于使用了表达式模板进行惰性求值,因此我需要返回类型推导。

Just for your information, I have a real use case of such code, where I try to wrap a third -party matrix class and I need return type deduction because of the use of expression template for lazy evaluation.

编辑:确实可以执行以下操作(但仍会使界面混乱……)

Edit: The following does work (but still clutters the interface...)

template<typename T>
class MyClass
{
    T impl;

public:
    explicit MyClass(T a) : impl(std::move(a)) { }

    T const& getImpl() const { return impl; }

    template<typename T0, typename T1>
    friend auto operator +(MyClass<T0> const& a, MyClass<T1> const& b) -> MyClass<decltype(a.impl + b.impl)>;
};

template<typename T0, typename T1>
auto operator +(MyClass<T0> const& a, MyClass<T1> const& b) -> MyClass<decltype(a.impl + b.impl)>
{
    return MyClass<decltype(a.impl + b.impl)>(a.impl + b.impl);
}


推荐答案

编辑:
看评论部分,它是gcc 4.8.2和4.9中的错误

edit:look at the comments section, it's a bug in gcc 4.8.2 and 4.9

Gcc错误代码:

这篇关于模板朋友功能和返回类型推导的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 18:41