我正在使用一对类型:
typedef std::pair<int, std::string> Nomnom;
示例放置它的使用:
void DoIt(const Nomnom &toNom) {
...
}
void DoItAgain(const Nomnom &toNomAgain) {
...
}
在我的情况下,如果未指定,则为该对提供默认值是有意义的。也就是说,我希望能够做到这一点:
DoIt("Thisisit");
DoItAgain("Thisisit");
并且它等同于:
DoIt(NomNom(0, "Thisisit"));
DoItAgain(NomNom(0, "Thisisit"));
我希望每次使用Nomnom
时都不要定义两个变体。
有没有办法完成为Nomnom而不是typedef定义一个类的缺点,提供一个arg构造函数,然后提供调用std::pair
构造函数的zero-arg和two-arg构造函数?
答案 0 :(得分:2)
原始问题
有没有办法完成为Nomnom定义一个类的缺点,提供一个arg构造函数,然后提供调用std :: pair构造函数的zero-arg和two-arg构造函数?
你可以有更多的构造函数重载
ClassNoms() : one(std::make_pair(-1,"") {}
ClassNoms(int id) : one(std::make_pair(id,"") {}
ClassNoms(const std::string& name) : one(std::make_pair(-1,name) {}
ClassNoms(int id, const std::string& name) : one(std::make_pair(id,name) {}
更新:
有没有办法完成为
Nomnom
而不是typedef
定义一个类的缺点,提供一个arg构造函数,然后提供零arg和两个arg构造函数调用std::pair
构造函数?
typedef std::pair<int, std::string> Nomnom;
您无法为typedef
&d; NomNom
提供默认构造函数,因为std::pair<>
并未提供构造函数。要实现这一点,您需要从NomNom
继承一个类std::pair<>
,或者恕我直接为它提供一个包装器,并使用它:
template<typename First,typename Second>
struct DefaultValuedPair {
std::pair<First,Second> value;
First& first;
Second& second;
DefaultValuedPair
( const First& first = First()
, const Second& second = Second()
)
: value(std::make_pair(first,second))
, first(value.first)
, second(value.second) {}
DefaultValuedPair(const std::pair<First,Second>& rhs)
: value(rhs)
, first(value.first)
, second(value.second) {}
// Add more implicit type conversions for std::pair<First,Second>
// as necessary ...
};
并且
typedef DefaultValuedPair<int, std::string> Nomnom;
你可以有一个就像一个构造函数的函数,但它不能被命名并被称为NomNom
(声明的)类型的纯等价,这就不会了#39; t优于使用std::make_pair()
。
建议的包装器解决方案可能会对重构使用NomNom
的现有代码的注意事项产生巨大影响,并且应该与此类无缝协作。如上所述,只是替换/伪装std::make_pair
本身,没有任何意义恕我直言。
答案 1 :(得分:2)
您无法轻松地将自己的构造函数添加到std::pair
(继承它并不是一个真正的选项)。
但是你可以提供一个小函数来构造它并相应地重载它:
Nomnom nomnom(const std::string& s) { return Nomnom(-1, s); }
Nomnom nomnom(int i) { return Nomnom(i, ""); }
您还可以重载DoIt
和DoItAgain
并转发常规实现。
void DoIt(const Nomnom& n) { /* ... */ }
void DoIt(int i) { DoIt(Nomnom(i, "")); }
答案 2 :(得分:1)
如果您正在使用C ++ 11,则可以从与using
配对继承构造函数。我认为这是解决问题的最简洁方法。
是否有理由(除了不想重新实现std::pair
的构造函数之外)你不想从std :: pair继承?
#include <utility>
#include <string>
#include <iostream>
/**
* Nomnom is just a std::pair with a customized constructor.
*/
class Nomnom : public std::pair <int, std::string> {
typedef std::pair<int, std::string> parent_type; // For convenience
public:
using parent_type::parent_type; // Inherit Pair's constructors
Nomnom (std::string S) : parent_type(0, S) {} // And add our own
Nomnom (char const * S) : parent_type(0, S) {} // Handle C strings...
};
/**
* Show that we can just use Nomnom as a std::pair...
*/
template <class FIRST, class SECOND>
std::ostream & operator<< (std::ostream & out, std::pair <FIRST, SECOND> const & print_me) {
return out << print_me.first << ", " << print_me.second << '\n';
}
/**
* Use this to test initizlization while passing to a method
*/
void foo (Nomnom const & print_me) {
std::cout << print_me;
}
int main (void) {
std::cout << Nomnom("Hello!");
std::cout << Nomnom(5, "World!");
foo ("Mouse!");
return 0;
}