簡體   English   中英

類模板的友元函數的顯式特化

[英]Explicit specialization of friend function for a class template

我正在閱讀 litb 對這里問題的回答,他詳細介紹了如何創建類模板專用友元函數

我試圖創建一個例子,它按照他的建議(最后的代碼):

// use '<>' to specialize the function template with the class template's type
friend std::ostream& operator<< <>(std::ostream& os, const foo<T>& f)

它導致編譯器錯誤

error: defining explicit specialization ‘operator<< <>’ in friend declaration

在專業化中顯式聲明模板參數也不起作用:

friend std::ostream& operator<< <T>(std::ostream& os, const foo<T>& f) // same error

另一方面,從使用特化改為使用友元函數模板確實有效:

template<typename U>
friend std::ostream& operator<<(std::ostream& os, const foo<U>& f) // this works

所以我的問題是:

  • 是什么導致了第一個錯誤?
  • 如何為周圍的類模板特化顯式特化ostream operator

示例代碼如下:

#include <iostream>

// fwd declarations
template<typename T> struct foo;
template<typename T> std::ostream& operator<<(std::ostream&, const foo<T>&);

template<typename T>
struct foo
{
    foo(T val)
        : _val(val)
    {}

    friend std::ostream& operator<< <>(std::ostream& os, const foo<T>& f) // error line
    //template<typename U>
    //friend std::ostream& operator<<(std::ostream& os, const foo<U>& f) // this works
    {
        return os << "val=" << f._val;
    }

    T _val;
};


int main()
{
    foo<std::string> f("hello world");
    std::cout << f << std::endl;
    exit(0);
}

在 litb 的示例中,他只是將專業化聲明為班級中的朋友。 他沒有定義專業化,這就是您的代碼所做的。 不允許在類聲明(或任何非命名空間范圍)中定義特化。

你需要的是這樣的:

template <class T>
class foo;

template<class T>
std::ostream& operator<<(std::ostream& os, const foo<T>& f)
{
    return os << "val=" << f._val;
}

template<typename T> 
struct foo
{
    // ...
private:
    friend std::ostream& operator<< <>(std::ostream& os, const foo<T>& f);
    T _val;
};

您有 2 個選擇:

刪除 fwd 聲明並在類中定義所有內容。

例子

template <typename U>
friend std::ostream& operator<<(std::ostream& os, const foo<U>& f) // this works
{
    return os << "val=" << f._val;
}

在類之外定義友元函數。

例子

template<typename T> struct foo;
template<typename T> std::ostream& operator<<(std::ostream&, const foo<T>&);

template<typename T>
struct foo
{
    foo(T val)
        : _val(val)
    {}

    friend std::ostream& operator<< <>(std::ostream& os, const foo<T>& f);

    T _val;
};

template <typename T>
std::ostream& operator<<(std::ostream& os, const foo<T>& f)
{
       return os << "val=" << f._val;
}

暫無
暫無

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

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