std :: ostream:类不可用[C ++]

时间:2017-12-03 02:50:26

标签: c++ c++11 inner-classes friend ostream

我在实施中遇到了这个错误:

  

struct bookdatabase :: Bookdatabase :: Book

     

class" bookdatabase :: BookDatabase :: Book"无法进入

以下解决方案均未解决我的问题:

Here's了解.cpp文件中visual studio遇到的问题。

Here's头文件中声明的图片。


Database.h

#include <string>
#include <vector>


#ifndef BOOKDATABASE_H
#define BOOKDATABASE_H

namespace bookdatabase {
    class BookDatabase {
    private:
        struct Book {
        private:
            std::string authorFirstName, authorLastName, authorFullName, bookTitle, pubDate;
        public:
            Book(const std::string &authFirst, const std::string &authLast, const std::string &title, const std::string &date);
            std::string getAuthor() const;
            std::string getBookTitle() const;
            std::string getPubDate() const;
            bool operator < (const Book &rhs) const;
            friend std::ostream& operator << (std::ostream& out, const bookdatabase::BookDatabase::Book& book);
        };
        void sortBooks();
        std::vector<Book>::iterator search(const std::string &title);
    public:
        BookDatabase();
        void printBookList();
        std::vector<Book> getDatabase() const;
        void removeBook(const std::string &title);

        void addBook(const std::string &authFirst, const std::string &authLast, const std::string &title, const std::string &date);
    private:
        std::vector<Book> database;
    };
}

#endif // BOOKDATABASE_H


Database.cpp

std::ostream & bookdatabase::operator<<(std::ostream & out, const bookdatabase::BookDatabase::Book & book) {
    out << authorFullName << ". " << bookTitle << ". " << pubDate;
    return out;
}


我是否遇到此问题,因为Book类是嵌套类?

2 个答案:

答案 0 :(得分:0)

好吧,我似乎在这里发现了两件可能是您遇到的问题,其中一件可能是Visual Studio中的错误。

1。首先,不是bug的东西

user0042,在对您的帖子的回复中是正确的,operator<<friend中被struct Book声明为operator<<只能访问Book的私有成员Book。但它无法访问Book本身,因为BookDatabase是封闭的Book类的私有成员。因此,您必须将好友声明移至BookDatabase之外和operator<<

完成此操作后,Book现在可以访问BookDatabase的私有数据成员operator<<。但请注意,这不允许Book访问authorFirstName, authorLastName, authorFullName, bookTitle, pubDate本身的私有数据成员,即BookDatabase

2A。现在为(我相信)VS2017范围操作符错误

假设您已将好友声明移至Database.cpp,您仍需要以特定方式定义实施。以下两段代码应该是在namespace bookdatabase { ostream& operator<<(ostream& out, const bookdatabase::BookDatabase::Book& book) { } } // OK 文件中定义函数的等效方法,但其中一条在VS2017 15.4.5 中不起作用。

可以

ostream& bookdatabase::operator<<(ostream& out, const bookdatabase::BookDatabase::Book& book) {
}  // Visual Studio cannot access book

但不好做

::

Visual Studio的friend运算符似乎存在一个问题,即能够获取函数的friend属性。

所以回答你的问题:如果你想要你的&lt;&lt;运算符重载需要使用第一种方法在.cpp实现文件中定义它。

2B。事实上我写了一个简单的测试程序来显示VS2017 ::namespace my_namespace { class Test { private: struct Nested {}; public: friend void func(Test::Nested&); }; void func(Test::Nested&); } // DOES NOT COMPILE in VS2017 15.4.5, OK in GCC 6.3 and Clang 3.8.0 // VS2017 says Nested is inaccessible void my_namespace::func(my_namespace::Test::Nested&) { } bug

namespace

但是使用namespace my_namespace { class Test { private: struct Nested {}; public: friend void func(Test::Nested&); }; void func(Test::Nested&); } // changed to namespace + brackets, // COMPILES in VS2017 15.4.5, GCC 6.3 and Clang 3.8.0 namespace my_namespace { void func(my_namespace::Test::Nested&) { } } 和括号可以

   public class Test
    {
        ConcurrentHashSet hashSet = new ConcurrentHashSet();
        public Test() 
        {
            foreach (ConcurrentHashSet set in hashSet.GetItemsById(123))
            {
            }
        }


    }

    public class ConcurrentHashSet : HashSet<ConcurrentHashSet>
    {
        public Boolean HasLoaded { get; set; }
        public int Id { get; set; }

        public List<ConcurrentHashSet> GetItemsById(int id)
        {
            return this.Where(x =>  x.HasLoaded && x.Id == id).ToList();
        }
    }

有人可以独立验证吗?

我还发布了bug report on the Microsoft Developer Community

答案 1 :(得分:0)

我对大多数运营商的答案&lt;&lt;困难是声明一个成员print()方法来完成艰苦的工作并从运算符&lt;&lt;中调用它。 通常我很高兴打印方法公开,并摆脱所有朋友的肮脏。