结构以优雅的方式串起来

时间:2018-01-19 08:31:42

标签: c++ struct

我有结构:

struct movies_t {
  string title;
  int year;
} 

我希望这个结构能够在字符串中显示它的字段。

std:string toString()
{
return "title=" title + "year="+ itostr(year);
}

我无法将struct更改为class,因为我应该将它传递给编译库,其中代码是未知的。实现这个的最佳方法是什么?

4 个答案:

答案 0 :(得分:4)

由于struct具有public可见性,您可以直接向结构注入成员函数来执行此操作,例如:

#include <iostream>
#include <string>

using namespace std;

struct movies_t {
  string title;
  int year;

  string toString()
  {
    return "title = " + title + ", year = " + to_string(year);
  }
};

int main()
{
    struct movies_t m{"Odyssey", -800};
    cout << m.toString() << endl;
}

输出:

  

title = Odyssey,year = -800

答案 1 :(得分:4)

有很多方法可以实现这一点。我赞成的是提供ADL自由函数to_string和运算符的重载&lt;&lt;。

添加了命名空间以展示ADL:

#include <string>
#include <ostream>
#include <sstream>
#include <iostream>

namespace movie
{
    struct movies_t {
      std::string title;
      int year;
    };

    std::ostream& operator<<(std::ostream& os, movies_t const& arg)
    {
        os << "title = " << arg.title << ", year = " << arg.year;
    }

    std::string to_string(movies_t const& arg)
    {
        std::ostringstream ss;
        ss << arg;
        return std::move(ss).str();  // enable efficiencies in c++17
    }
}

int main()
{
    auto m = movie::movies_t { "Star Wars", 1977 };

    std::cout << m << '\n';

    using std::to_string;
    std::cout << to_string(m) << '\n';
}

答案 2 :(得分:1)

如果你不能编辑结构,你可能想要包装另一个类

class MoviesExpansion {
public:
    MoviesExpansion(std::string title, int year) // Initialize movie in constructor
    {
        movies.title = title;
        movies.year = year;
    }

    movies_t& getMovies() { return movies; } // To get the raw movie for passing to the library.

private:
    movies_t movies; // The struct to add the additional functionality

    std::string toString() // The function we want to add
    {
        return "title = " + movies.title + " | year = " + std::to_string(movies.year);
    }
}

然后你可以做

int main()
{
    MoviesExpansion myMovies("Movie Title", 2018); // Create MoviesExpansion containing an movies_t structure

    std::cout << myMovies.toString(); // Outputs "title = Movie Title | year = 2018"

    someCompiledLibraryFunction(myMovies.getMovies()); //Call lib function

    myMovies.getMovies().title = "New Title"; // Change Movie Title

    std::cout << myMovies.toString(); // Outputs "title = New Title | year = 2018"

   return 1;

}

答案 3 :(得分:1)

您可以使该成员函数const确保只有标记为mutable的成员才可以修改。

#include <iostream>
#include <sstream>

struct movies_t {
    std::string title;
    int year;

    std::string _to_string() const {
        std::ostringstream stream_out;
        stream_out << "title: " << title << " year: " << year;
        return stream_out.str();
    }

    std::string toString() const {
        return "title = " + title + " year = " + std::to_string(year);
    }
};

std::ostream& operator<<(std::ostream& stream_out, const movies_t& M) {
    stream_out << M.title << " " << M.year;
    return stream_out;
}

std::string _to_string(const movies_t M) {
    std::ostringstream stream_out;
    stream_out << M.title << " " << M.year;
    return stream_out.str();
}

int main() {

    movies_t N{"Friends", 1994};

    std::cout << N << std::endl;
    std::cout << _to_string(N) << std::endl;
    std::cout << N._to_string() << std::endl;
    std::cout << N.toString() << std::endl;

    return 0;
}