如何定义从标准类型到用户定义类型的转换?

时间:2019-06-22 04:10:28

标签: c++ type-conversion

我正在处理一个C ++文件,该文件可以执行霍夫曼编码,并且在从字符串类型和整数类型的映射更改为Node的队列时遇到了一个问题,并且想知道是否存在一种定义从一对字符串和整数到Node的显式转换的方法。

目前,我拥有这样的功能,以便将映射转换为成对的向量,然后转换为类型为Node的向量,然后转换为类型为Node的优先级队列。

// this->char_freqs is of type map<std::string, int>
std::vector<std::pair<std::string, int> > my_vector(this->char_freqs.begin(), this->char_freqs.end());
  std::vector<Huffman::Node*> real_vector;
  for (unsigned int i = 0; i < my_vector.size(); ++i) {
    real_vector.push_back(new Huffman::Node(my_vector[i].first, my_vector[i].second));
  }
  std::priority_queue<Huffman::Node*, std::vector<Huffman::Node*>, Huffman::comp> PQ(real_vector.begin(), real_vector.end());

我还没有测试这是否行得通。但是,我更希望开发一种可以显式定义从pair<string, int>Node*的转换的方法,以便从映射到队列的转换基本上可以在一行中完成。像这样:

std::priority_queue<Huffman::Node*, std::vector<Huffman::Node*>, Huffman::comp> PQ(this->char_freqs.begin(), this->char_freqs.end());

在阅读文档时,我仅找到了将用户定义类型转换为默认类型的示例,而没有相反的例子。

编辑1

希望它应该更简单,并解释我要寻找的内容。

class Node {
 public:
  char character;
  int frequency;
  Node(char char_, int val_) {
    character = char_;
    frequency = val_;
  }
  operator std::pair<char, int>() {
    return std::pair<char, int>(character, frequency);
  }
};
int main(int argc, char** argv) {
  std::vector<std::pair<char, int> > my_vector_1;
  Node n('a', 3);
  my_vector_1.push_back(n); // Can use a Node as an input since the conversion has been explicitly defined

  std::vector<Node> my_vector_2;
  std::pair<char, int> pair('a', 3);
  my_vector_2.push_back(pair); // Invalid
}

当然,invalid选项会失败,因为编译器无法将一对转换为Node,但是是否有可能使无效行起作用?

2 个答案:

答案 0 :(得分:2)

如果我正确理解了您的问题,那么您需要的是Node的另一个构造函数,诸如此类

Node(const std::pair<char, int>& pair) : character{pair.first}, 
                                         frequency{pair.second} { }

请注意,我正在使用成员初始化程序列表来初始化您的类的数据。建议您这样做,有关更多信息,请参见https://en.cppreference.com/w/cpp/language/initializer_list

展望未来,您可能希望将构造函数标记为explicit以避免不必要的转换(请参见What does the explicit keyword mean?),并使用emplace_back而非push_back来避免构造a临时https://en.cppreference.com/w/cpp/container/vector/emplace_back。将构造函数标记为explicit可能不适合您的用例,您可以选择。如果您将构造器explicit标记为现在编写的push_back将停止工作,则需要显式创建Node或使用emplace_back

答案 1 :(得分:1)

问题出在Implicit conversion下。
隐式转换是根据复制初始化定义的:if an object of type T can be copy-initialized with expression E, then E is implicitly convertible to T.
现在考虑以下示例,

#include <iostream>
#include <utility>

class Point
{
public:
    Point():x(),y()
    {
    }

    Point( const std::pair< int, int>& pair):
        x( pair.first),
        y( pair.second)
    {

    }

    int getX() const
    {
        return x;
    }

    int getY() const
    {
        return y;
    }

private:
    int x;
    int y;
};

int main(int , char *[])
{
    Point p = std::pair< int, int>( 1, 2);
    std::cout<< "x = "<< p.getX()<< ", y = "<< p.getY()<< std::endl;

    return 0;
}

输出x = 1, y = 2

此处std::pair< int, int>可隐式转换为Point类型。
另一点是,如果您将explicitPoint( const std::pair< int, int>& pair)一起使用,则无法使用上述语法,在这种情况下,您必须将其修改为Point p( std::pair< int, int>( 1, 2));
有关更多信息,请参见以下链接copy_initialization