簡體   English   中英

模板友好功能和返回類型扣除

[英]Template friend function and return type deduction

注意:這個問題非常接近於類內朋友函數的返回類型推導 ,但我沒有在那里找到我的問題的答案。

用clang 3.4測試std = c ++ 1y和clang 3.5用std = c ++ 14和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 +,它就不再編譯了:

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};
}

Clang 3.4說:

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

然后指出它認為是兩個不同的函數:類中的聲明和類外的定義。

我的問題是:它是一個鏗鏘的錯誤,還是僅僅為朋友函數推導出模板參數,從而導致兩個函數不相等是某些情況? 你會建議什么樣的選擇:make operator +一個成員函數,或者在類中定義friend operator +(在我看來會混淆類接口)?

僅僅為了您的信息,我有一個這樣的代碼的真實用例,我嘗試包裝第三方矩陣類,我需要返回類型推導,因為使用表達式模板進行延遲評估。

編輯 :以下工作(但仍然使界面混亂...)

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中的錯誤

Gcc錯誤代碼:

prog.cpp:10:61:錯誤:非靜態數據成員聲明'auto'運算符+(MyClass const&a,MyClass const&b)^ prog.cpp:在函數'int main()'中:prog.cpp:25:15 :錯誤:'operator +'不匹配(操作數類型是'MyClass'和'MyClass')auto z = x + y; ^

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM