在C#中我可以这样写:
class AnyThing<T>
{
static public T Default = default(T);
}
static void Main ()
{
int i = AnyThing<int>.Default;
Console.WriteLine (i==0);
string s = AnyThing<string>.Default;
Console.WriteLine (s == null);
}
Run Code Online (Sandbox Code Playgroud)
我打算在C++中写一个类似模板类的字典,如果找不到给定的密钥,我希望dict返回通用TVal类型的默认值(零输出).在C#中,默认(T)构造来拯救,而在C++中,我不确定做同样事情的适当方法是什么.
我试着T obj = {}和T* obj = {}用gcc4.7,它工作得很好.我只是不确定它是否是语言规范定义的语法,如果这种类型的代码将是可移植的交叉编译器和平台.我的doudt请帮帮我!提前致谢!
PS:
~~~~~~~~~~
为了确保模板获得ANY类型的默认(零输出)值,即使是那些没有可调用默认ctor的值,我采用了以下机制(受avakar的回答启发):
template<class T>
struct AnyThing
{
static const T& Default ;
private:
static const char temp[sizeof(T)];
};
template<class T> const char AnyThing<T>::temp[] = {};
template<class T> const T& AnyThing<T>::Default = *(T*)temp;
struct st
{
double data;
st()=delete;
};
int main()
{
cout << (int)AnyThing<char*>::Default<<endl; //0
cout << AnyThing<int>::Default<<endl; //0
cout <<AnyThing<st>::Default.data<<endl; //0
}
Run Code Online (Sandbox Code Playgroud)
它看起来很丑,但不应该造成任何麻烦,毕竟归零的对象只是一大块空白内存.我错了吗?
For*_*veR 22
在C++ default中,C#中没有像关键字这样的东西.由于默认构造函数是默认构造函数,因此默认情况下初始化类型的值构造函数将失败private.在C#中,如果默认构造函数是私有的,则class-type的值将被初始化为null,因为class-type是reference-type.
Initialition by {}由语言规范定义.这是C++ 11.在C++ 03中你应该使用
T obj = T();
Run Code Online (Sandbox Code Playgroud)
正如bames53在评论中指出的那样,当你想要初始化时,T*你应该使用
在C++ 11之前.
T* obj = 0;
Run Code Online (Sandbox Code Playgroud)
要么
T* obj = NULL;
Run Code Online (Sandbox Code Playgroud)
在C++ 11中.
T* obj = {};
Run Code Online (Sandbox Code Playgroud)
要么
T* obj = nullptr;
Run Code Online (Sandbox Code Playgroud)
摘自"Cj编程语言,Bjarne Stroustrup第三版":
开始报价
4.9.5初始化[dcl.init]
如果为对象指定了初始值设定项,则该初始值设定项将确定对象的初始值.如果未指定初始化程序,则将全局(第4.9.4节),名称空间(第8.2节)或本地静态对象(第7.1.2节,第10.2.2节)(统称为静态对象)初始化为适当类型的0 .例如:
int a; // means int a=0;
double d; // meands d=0;
Run Code Online (Sandbox Code Playgroud)
默认情况下,不会初始化本地变量(有时称为自动对象)和在空闲存储上创建的对象(有时称为动态对象或堆对象).例如:
void f()
{
int x; // x does not have a well-defined value
// . . .
}
Run Code Online (Sandbox Code Playgroud)
数组和结构的成员是默认初始化的,具体取决于数组或结构是否为静态.用户定义的类型可能已定义默认初始化(第10.4.2节).
更复杂的对象需要多个值作为初始化程序.这由由{和}分隔的初始化列表处理,用于数组的C样式初始化(第5.2.1节)和结构(第5.7节).
对于具有构造函数的用户定义类型,使用函数式参数列表(第2.5.2节,第10.2.3节).请注意,声明中的一对空括号()始终表示''function''(第7.1节).例如:
int a[] = {1,2}; // array initializer
Point z(1,2); // function-style initializer (initialization by constructor)
int f(); // function declaration
Run Code Online (Sandbox Code Playgroud)
结束语
因此,您可以从该类型的静态对象获取任何类型的默认值:
static T defaultT; // `defaultT' has de default value of type T
Run Code Online (Sandbox Code Playgroud)
创建您自己的默认关键字:
class default_t
{
public:
template<typename T>
operator T() const { return T(); }
};
default_t const default = default_t();
Run Code Online (Sandbox Code Playgroud)
像这样使用它:
int myInt = default;
vector<string> myVector = default;
shared_ptr<string> myPtr = default;
Run Code Online (Sandbox Code Playgroud)
或者有轻微的语义变化:
default_t const empty = default_t();
vector<Persons> fetchPersons()
{
if (Database::isConnected())
{
return Database::fetchPersons();
}
return empty;
}
Run Code Online (Sandbox Code Playgroud)