2015-04-05 87 views
0

假设我正在创建一个类client。我想client能够以下几类构成:C++简化构造函数重载

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 &) 

它可以假设我的客户类,为简单起见,简单来说,如下所示。

#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个以上的变量进行排列,这会变得很难看,很快。

+0

如果'uri'有接受'的std :: string'或'字符常量*'构造函数,你将能够减少很多构造函数。 – 2015-04-05 01:59:27

+0

@RSahu它! C++是否执行某种隐式类型初始化? – 2015-04-05 01:59:50

+0

编译器将最多使用一个用户定义的转换。有关更多详细信息,请参见http://en.cppreference.com/w/cpp/language/cast_operator。 – 2015-04-05 02:04:05

回答

1

如何模板:

#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)) 
    { } 

    // ... 
}; 
+0

要使构造函数成为模板,是否需要模板类? 报出了构造一个模板并没有多大意义...... [见此帖](http://stackoverflow.com/questions/3960849/c-template-constructor) – 2015-04-05 02:53:10

+0

@FranciscoAguilera:你链接的帖子,而无需实际阅读答案的前两句,methinks。 – 2015-04-05 03:34:21

+0

@BenVoigt不,我没有读过它,但是,上面的代码产生以下错误:'构造函数不能有返回类型',这导致我相信它不能用构造函数完成,正如我所说的。 – 2015-04-05 03:35:42

1

由于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)){} 

“我怎么就委托给这个构造特别?” 使用委托构造函数时应该明确。

client(const char * && host, const char * && auth) : 
      client(uri(host), uri(auth)){} 

client(const char * && host, const char * && auth) : 
      client(string(host), string(auth)){} 
+0

好吧,以便回答你以前的观察提出的一个问题:P但是,我仍然留有原始问题。如何排列构造函数参数的所有组合,以及由于参数是右值引用类型而导致的一些问题。 – 2015-04-05 02:28:37

+0

@FranciscoAguilera,我最初的建议是为了避免与'什么,但'uri'作为参数类型client'构造函数,这会减少你必须处理构造的数量。 – 2015-04-05 02:31:30

+0

另外,@Rsahu,'客户端C( “”,“”);'给出一个错误:'没有匹配的客户端初始化构造函数'。因此C++不会像uri一样自动执行用户定义的转换。 – 2015-04-05 03:05:19

1

可以使能采取所有的这三样东西作为参数的类。您的文章没有包括足够的细节,我写了一个具体的答案,但这里是伪代码:

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); 
+0

“你可以创建一个单独的类,它可以将所有这三件事情作为参数。”马特,通过这样做,你不是把创建这些重载构造函数的责任委托给这样的类吗? – 2015-04-05 03:41:28

+0

@FranciscoAguilera是的,但你只有3个构造函数写(这都将是简单的),再加上主'client'构造函数,而不是9 – 2015-04-05 03:42:10

+0

嗯,看来这样过于复杂的xD 在现实中,我只需要在传递2个uri对象。但是它简化了我的代码,使其能够以其他类型传递:'string'和'const char *',特别是因为这样的代码不再需要包含uri的头文件。 – 2015-04-05 03:46:20