2015-04-05 101 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