[英]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
專門化這個類。 不幸的是,你必須專注於整個班級,因為沒有個別成員的選擇性專業化。 因此,在這種情況下,您可能希望將所有代碼移動到一個公共(可能是private
的Value
基類,其中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.