C++ 简化构造函数重载
C++ simplify constructor overloads
假设我正在制作 class client
。我希望 client
能够用以下类型构造:
client(const boost::network::uri::uri &, const boost::network::uri::uri &)
client(const std::string &, const std::string &)
client(const char *, const char *)
但是...我也想要所有的排列...
client(const boost::network::uri::uri &, const boost::network::uri::uri &)
client(const std::string &, const std::string &)
client(const char * &, const char * &)
client(const boost::network::uri::uri &, const std::string &)
client(const std::string &, const boost::network::uri::uri &)
client(const boost::network::uri::uri &, const char * &)
client(const char * &, const boost::network::uri::uri &)
client(const std::string &, const char * &)
client(const char * &, const std::string &)
可以假设我的客户 class 为简单起见被简化后如下所示。
#include <string>
#include <boost/network.hpp>
#define HOST_URI "..."
#define AUTH_URI HOST_URI"..."
namespace bn = boost::network;
class client
{
private:
const bn::uri::uri host_;
const bn::uri::uri auth_;
public:
client(const bn::uri::uri & host = const bn::uri::uri(HOST_URI),
const bn::uri::uri & auth = const bn::uri::uri(AUTH_URI));
client(const std::string & host = const std::string(HOST_URI),
const std::string & auth = const std::string(AUTH_URI));
client(const char * & host = HOST_URI,
const char * & auth = AUTH_URI);
client(const bn::uri::uri & host = const bn::uri::uri(HOST_URI),
const std::string & auth = const std::string(AUTH_URI));
client(const std::string & host = const std::string(HOST_URI),
const bn::uri::uri & auth = const bn::uri::uri(AUTH_URI));
client(const bn::uri::uri & host = const bn::uri::uri(HOST_URI),
const char * & auth = AUTH_URI);
client(const char * & host = HOST_URI,
const bn::uri::uri & auth = const bn::uri::uri(AUTH_URI));
client(const std::string && host = const std::string(HOST_URI),
const char * & auth = AUTH_URI);
client(const char * & host = HOST_URI,
const std::string && auth = const std::string(AUTH_URI));
};
目前定义为:
#include <string>
#include <boost/network.hpp>
namespace bn = boost::network;
client::client(const bn::uri::uri & host,
const bn::uri::uri & auth)
: host_(host), auth_(auth)
{
...
};
client::client(const std::string & host,
const std::string & auth)
: client(bn::uri::uri(host), bn::uri::uri(auth)){}
client::client(const char * & host,
const char * & auth)
: client(bn::uri::uri(host), bn::uri::uri(auth)){}
client::client(const bn::uri::uri & host,
const std::string & auth)
: client(host, bn::uri::uri(auth)){}
client::client(const std::string & host,
const bn::uri::uri & auth)
: client(bn::uri::uri(host), auth){}
client::client(const bn::uri::uri & host,
const char * & auth)
: client(host, bn::uri::uri(auth)){}
client::client(const char * & host,
const bn::uri::uri & auth)
: client(bn::uri::uri(host), auth){}
client::client(const std::string & host,
const char * & auth)
: client(bn::uri::uri(host), bn::uri::uri(auth)){}
client::client(const char * & host,
const std::string & auth)
: client(bn::uri::uri(host), bn::uri::uri(auth)){}
所以我的问题是,执行此操作的正确且简单的方法是什么?
当然,这次我手动完成了所有排列,但将来我可以有 3 个以上的变量来排列,这会变得很丑陋,很快。
由于uri定义了既可以带string
又可以带const char *
的构造函数,剔除参数不包含uri类型参数的构造函数。这让 uri 的 user-defined conversion 隐式地为你转换这些类型。
#define HOST_URI "..."
#define AUTH_URI HOST_URI"..."
class client
{
private:
uri host_;
uri auth_;
public:
client(const uri & host = uri(HOST_URI),
const uri & auth = uri(AUTH_URI));
client(const char * host = HOST_URI,
const char * auth = AUTH_URI);
};
-
client::client(const uri::uri & host,
const uri::uri & auth)
: host_(host), auth_(auth)
{
...
};
client::client(const char * host,
const char * auth)
: client(uri::uri(host), uri::uri(auth)){}
"How do I delegate it to that constructor specifically?"
使用委托构造函数时要明确。
client(const char * && host, const char * && auth) :
client(uri(host), uri(auth)){}
或
client(const char * && host, const char * && auth) :
client(string(host), string(auth)){}
模板如何:
#include <type_traits>
class client
{
uri host_;
uri auth_;
public:
template <typename U, typename V,
typename = typename std::enable_if<
std::is_constructible<uri, U&&>::value &&
std::is_constructible<uri, V&&>::value>::type>
client(U && u, V && v)
: host_(std::forward<U>(u))
, auth_(std::forward<V>(v))
{ }
// ...
};
您可以制作一个 class,它可以将所有这三样东西作为参数。你的 post 没有包含足够的细节让我写一个具体的答案,但这是伪代码:
struct input_helper
{
input_helper(uri &u);
input_helper(string &u);
input_helper(char *u);
// data members to hold the inputs, maybe other processing to bring them to a common type
};
// the constructor
client(input_helper host, input_helper auth);
假设我正在制作 class client
。我希望 client
能够用以下类型构造:
client(const boost::network::uri::uri &, const boost::network::uri::uri &)
client(const std::string &, const std::string &)
client(const char *, const char *)
但是...我也想要所有的排列...
client(const boost::network::uri::uri &, const boost::network::uri::uri &)
client(const std::string &, const std::string &)
client(const char * &, const char * &)
client(const boost::network::uri::uri &, const std::string &)
client(const std::string &, const boost::network::uri::uri &)
client(const boost::network::uri::uri &, const char * &)
client(const char * &, const boost::network::uri::uri &)
client(const std::string &, const char * &)
client(const char * &, const std::string &)
可以假设我的客户 class 为简单起见被简化后如下所示。
#include <string>
#include <boost/network.hpp>
#define HOST_URI "..."
#define AUTH_URI HOST_URI"..."
namespace bn = boost::network;
class client
{
private:
const bn::uri::uri host_;
const bn::uri::uri auth_;
public:
client(const bn::uri::uri & host = const bn::uri::uri(HOST_URI),
const bn::uri::uri & auth = const bn::uri::uri(AUTH_URI));
client(const std::string & host = const std::string(HOST_URI),
const std::string & auth = const std::string(AUTH_URI));
client(const char * & host = HOST_URI,
const char * & auth = AUTH_URI);
client(const bn::uri::uri & host = const bn::uri::uri(HOST_URI),
const std::string & auth = const std::string(AUTH_URI));
client(const std::string & host = const std::string(HOST_URI),
const bn::uri::uri & auth = const bn::uri::uri(AUTH_URI));
client(const bn::uri::uri & host = const bn::uri::uri(HOST_URI),
const char * & auth = AUTH_URI);
client(const char * & host = HOST_URI,
const bn::uri::uri & auth = const bn::uri::uri(AUTH_URI));
client(const std::string && host = const std::string(HOST_URI),
const char * & auth = AUTH_URI);
client(const char * & host = HOST_URI,
const std::string && auth = const std::string(AUTH_URI));
};
目前定义为:
#include <string>
#include <boost/network.hpp>
namespace bn = boost::network;
client::client(const bn::uri::uri & host,
const bn::uri::uri & auth)
: host_(host), auth_(auth)
{
...
};
client::client(const std::string & host,
const std::string & auth)
: client(bn::uri::uri(host), bn::uri::uri(auth)){}
client::client(const char * & host,
const char * & auth)
: client(bn::uri::uri(host), bn::uri::uri(auth)){}
client::client(const bn::uri::uri & host,
const std::string & auth)
: client(host, bn::uri::uri(auth)){}
client::client(const std::string & host,
const bn::uri::uri & auth)
: client(bn::uri::uri(host), auth){}
client::client(const bn::uri::uri & host,
const char * & auth)
: client(host, bn::uri::uri(auth)){}
client::client(const char * & host,
const bn::uri::uri & auth)
: client(bn::uri::uri(host), auth){}
client::client(const std::string & host,
const char * & auth)
: client(bn::uri::uri(host), bn::uri::uri(auth)){}
client::client(const char * & host,
const std::string & auth)
: client(bn::uri::uri(host), bn::uri::uri(auth)){}
所以我的问题是,执行此操作的正确且简单的方法是什么? 当然,这次我手动完成了所有排列,但将来我可以有 3 个以上的变量来排列,这会变得很丑陋,很快。
由于uri定义了既可以带string
又可以带const char *
的构造函数,剔除参数不包含uri类型参数的构造函数。这让 uri 的 user-defined conversion 隐式地为你转换这些类型。
#define HOST_URI "..."
#define AUTH_URI HOST_URI"..."
class client
{
private:
uri host_;
uri auth_;
public:
client(const uri & host = uri(HOST_URI),
const uri & auth = uri(AUTH_URI));
client(const char * host = HOST_URI,
const char * auth = AUTH_URI);
};
-
client::client(const uri::uri & host,
const uri::uri & auth)
: host_(host), auth_(auth)
{
...
};
client::client(const char * host,
const char * auth)
: client(uri::uri(host), uri::uri(auth)){}
"How do I delegate it to that constructor specifically?" 使用委托构造函数时要明确。
client(const char * && host, const char * && auth) :
client(uri(host), uri(auth)){}
或
client(const char * && host, const char * && auth) :
client(string(host), string(auth)){}
模板如何:
#include <type_traits>
class client
{
uri host_;
uri auth_;
public:
template <typename U, typename V,
typename = typename std::enable_if<
std::is_constructible<uri, U&&>::value &&
std::is_constructible<uri, V&&>::value>::type>
client(U && u, V && v)
: host_(std::forward<U>(u))
, auth_(std::forward<V>(v))
{ }
// ...
};
您可以制作一个 class,它可以将所有这三样东西作为参数。你的 post 没有包含足够的细节让我写一个具体的答案,但这是伪代码:
struct input_helper
{
input_helper(uri &u);
input_helper(string &u);
input_helper(char *u);
// data members to hold the inputs, maybe other processing to bring them to a common type
};
// the constructor
client(input_helper host, input_helper auth);