簡體   English   中英

為模板化內部類重載非成員運算符

[英]Overloading of a non-member operator for a templated inner class

我無法弄清楚為什么編譯器無法看到或使用operator<< ( std::ostream & os, typename A<T>::B const& b )

#include <vector>
#include <iostream>


template <typename T> 
struct A
{
    struct B
    {
        std::vector<T> innervec;
    };

   std::vector<B> outervec;
};

template <typename T>
auto operator<< ( std::ostream & os, typename A<T>::B const& b ) -> std::ostream& 
{
    for (auto e : b.innvervec)
        os << "\n\t" << e;

    return os;
}

template <typename T>
auto operator<< ( std::ostream & os, A<T> const& a ) -> std::ostream& 
{
    for (auto e : a.outervec)
        os << '\n' << e;

   return os;
}

int main()
{
   A<int> a;
   A<int>::B b1;
   A<int>::B b2;
   b1.innervec.push_back( 11 );
   b1.innervec.push_back( 12 );
   b2.innervec.push_back( 21 );
   b2.innervec.push_back( 22 );
   a.outervec.push_back( b1 );
   a.outervec.push_back( b2 );
   std::cout << a << std::endl;
}

在VC ++ 15上給出了以下錯誤:

error C2679: binary '<<': no operator found which takes a right-hand operand of type 'A<int>::B' (or there is no acceptable conversion)

並且它也不能在GCC上編譯(盡管只在在線編譯器中嘗試過)。

我想有一個關於范圍和演繹的規則,但我無法確切地找出。

錯誤是因為嵌套類型的重載包含非推導的上下文參數typename A<T>::B const& b ,對於不能提供顯式模板參數T的運算符,您需要將運算符定義為嵌套的A<T>::B為:

template <typename T>
struct A
{
    struct B
    {
        std::vector<T> innervec;
        friend auto operator<< ( std::ostream & os, B const& b ) -> std::ostream&
        {
            for (auto e : b.innervec)
                os << "\n\t" << e;

            return os;
        }
    };

    std::vector<B> outervec;
};

有問題的部分是參數列表中的A<T>::B ,因為編譯器不能推導出這種形式的類型表達式,因為成員B存在和類型依賴於T 我會直接將b參數的類型作為模板參數T ,並使用SFINAE來約束已接受的類型。

暫無
暫無

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

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