簡體   English   中英

將構造函數添加到模板化類

[英]add constructor to templated class

我有一個模板化的類持有一個值。 是否可以在類中添加構造函數以允許隱式轉換,如下例所示?

或者有更好的方法嗎?

#include <string>

template<typename T>
class Value
{
  public:
    Value(const T& value) : m_value(value) { };
  private:
    T m_value;
};

// I thought adding something like this would do the trick but it does not work:
/*
template<>
class Value<std::string>
{
  public:
    Value(const char *sz) : m_value(sz) { };
}
*/

void f(const Value<std::string> &s)
{
}

int main()
{
  f(std::string("hello"));

  // I want to have this working:
  f("hello");
}

使用字符串文字調用f(const Value<std::string>&)將需要兩個用戶定義的轉換( const char[] ==> std::string ==> Value<std::string> )以便匹配函數參數,而標准只允許一個。
我看到兩種可能性來解決這個問題:重載構造函數或重載f()

假設您詢問前者,因為后者是不可能的,有幾種方法可以重載構造函數。

您可以利用這樣一個事實,即只有在調用類模板的成員函數時才會編譯它們,並添加一個僅在T屬於某種類型時才編譯的構造函數。 當然,如果模板的用戶為其他類型調用它,則會導致錯誤。 但是,您可以通過使構造函數成為成員模板來接受它,而不是在此處看到問題:

template<typename U>
Value(const U& value) : m_value(value) { };

這樣, U可以轉換為T (當然也可以是T本身)。

或者你可以為std::string專門化這個類。 不幸的是,你必須專注於整個班級,因為沒有個別成員的選擇性專業化。 因此,在這種情況下,您可能希望將所有代碼移動到一個公共(可能是privateValue基類,其中Value base模板只定義轉發到基類的構造函數的構造函數,以及一個特化Value<std::string>它添加了另一個采用const char*構造const char*

你不能。 這是C ++設計者的明確決定。 原因是編譯器需要尋找可能的轉換,並且通常這將是無限的搜索。

當然,您認為const char[] ==> std::string ==> Value<std::string>是合乎邏輯的。 但是編譯器沒有std::string 它只有const char[] ==> ??? ==> Value<std::string> ,它需要在中間找到一個類型。 例如,某個class Foo可能有一個Foo::Foo(const char*)構造函數,以及一個Foo::operator Value<std::string>() const 那也行。

如您所見, const char[]Value<std::string>沒有指向Foo的內容。 因此,編譯器必須進行盲目搜索。

作為Value ,你確實有一個選擇。 您可以通知編譯器可以從std :: string :: string接受的任何類型構造Value<std::string>

template<typename T>
class Value
{
  public:
    Value(const T& value) : m_value(value) { };
    // Intentionally not "explicit"
    template<typename U> Value(const U& value) : m_value(value) { };
  private:
    T m_value;
};

現在,如果將void f(const Value<std::string> &s)稱為f("hello") ,則會有一個隱式轉換Value<std::string>::Value<const char*>(const char* const&)

您無法像這樣添加到類中,但您可以專門化整個類。

試試這個

template<typename T>
class Value
{
  public:
    Value(const T& value) : m_value(value) { }
    Value(const char* a): m_value(a){} // add this
  private:
    T m_value;
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM