c#在c++中的默认关键字等价?

时间:2022-09-01 09:40:50

In C# I know you can use the default keyword to assign default values as 0 to value types and null to reference types and for struct types individual members are assigned accordingly. To my knowledge there are no default values in C++. What approach would you take to get the same functionality as the default keyword for Generics while programming in C++?

在c#中,我知道您可以使用default关键字为值类型赋值为0,为引用类型赋值为null,为结构类型赋值为每个成员。据我所知,c++中没有默认值。在c++中编程时,您会采用什么方法来获得和默认的泛型关键字相同的功能呢?

7 个解决方案

#1


11  

Assuming the type is default-constructible, you can use value initialization. For example,

假设类型是默认构造的,可以使用值初始化。例如,

template <typename T>
T get()
{
    return T(); // returns a value-initialized object of type T
}

If the type is not default-constructible, typically you need to provide a default to use. For example,

如果类型不是默认构造的,通常需要提供一个默认值来使用。例如,

template <typename T>
T get(const T& default_value = T())
{
    return default_value;
}

This function can be called with no argument if the type is default-constructible. For other types, you can provide a value to be returned.

如果类型是默认构造的,可以不带参数地调用此函数。对于其他类型,您可以提供要返回的值。

#2


2  

C++ doesn't have the default keyword, because it doesn't have the distinction between reference and value types. In C++, all types are what C# would consider value types, and if they're default constructible (as built-in types, POD structs and class types with default constructors are), they are initialized using value initialization (the default constructor syntax), as James McNellis showed: (and shamelessly copied here)

c++没有默认关键字,因为它没有引用类型和值类型之间的区别。在c++中,所有类型都是c#所考虑的值类型,如果它们是默认的可构造性(如内置类型、POD结构和类类型的默认构造函数),则使用值初始化(默认构造函数语法)来初始化它们,正如James McNellis所展示的那样:(并在此处不加修饰地复制)

template <typename T>
T get()
{
    return T(); // returns a value-initialized object of type T
}

if T has a default constructor, it is invoked. If it has no constructors, everything is initialized to zero/null.

如果T有一个默认构造函数,则调用它。如果没有构造函数,则将所有内容初始化为0 /null。

And if the type is not default constructible, there is no default value the object could be given.

如果类型不是默认可构造的,则不存在对象的默认值。

#3


0  

Use a default constructor, it's used even if you leave off the () at the end:

使用默认构造函数,即使您在结束时省略了(),也会使用它:

#include <iostream>
class MyClass {
    public:
    int x;
    MyClass(){
        x = 5;
    }
};

int main(){
    MyClass y;
    std::cout << y.x;
}

#4


0  

In C++, assigning a default value to a variable in global scope or in a function is as simple as:

在c++中,将一个默认值赋给全局作用域或函数中的一个变量,简单如下:

int myint=2;
float* pfloat=NULL;

For class members, you need to initialise these in the class's constructor:

对于类成员,您需要在类的构造函数中初始化它们:

class myclass {
private:
  int i;
public:
  myclass() {
    i = 4;
  }
};

I'm not sure about structures.

我不确定结构。

#5


0  

In C++, you'd typically invoke the default constructor (the constructor that may be called with no arguments). This works for primitive types too (that is, int() is 0, int*() is the null pointer, etc.).

在c++中,通常会调用默认构造函数(可以不带参数调用的构造函数)。这也适用于基本类型(即int()是0,int*()是空指针,等等)。

For example, in your template function, you'd write something like:

例如,在模板函数中,您可以编写如下内容:

template<typename T>
T foo()
{
    T x = T(); // See notes below about this.

    // Do other stuff.

    return x;
}

Note that T x; by itself would be sufficient to implicitly invoke a default constructor for non-POD types, but that wouldn't work for primitive scalar types (such as int) where it would be initialized to garbage. (T x() also wouldn't work; that would be interpreted as a function declaration.)

注意,T x;它本身就足以隐式地调用非pod类型的默认构造函数,但是对于初始化到垃圾的原始标量类型(比如int)来说,这是行不通的。(T x()也不起作用;这将被解释为函数声明。

#6


0  

Here is a quick summary of initialization techniques in C++03.

下面简要介绍c++ 03中的初始化技术。

To zero-initialize an object of type T means: — if T is a scalar type (3.9), the object is set to the value of 0 (zero) converted to T;

对于零初始化类型为T的对象意味着:-如果T是标量类型(3.9),则将对象设置为转换为T的0(0)的值;

— if T is a non-union class type, each nonstatic data member and each base-class subobject is zeroinitialized;

— if T is a union type, the object’s first named data member89) is zero-initialized;

— if T is an array type, each element is zero-initialized;

— if T is a reference type, no initialization is performed.

To default-initialize an object of type T means:

对于默认初始化的对象类型T意味着:

— if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);

— if T is an array type, each element is default-initialized;

— otherwise, the object is zero-initialized.

To value-initialize an object of type T means: >

对于值初始化的对象,类型T的意思是:>。

— if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);

— if T is a non-union class type without a user-declared constructor, then every non-static data member and base-class component of T is value-initialized;

— if T is an array type, then each element is value-initialized;

— otherwise, the object is zero-initialized

With that understanding

好理解的

struct S{
   int x;
   S():x(1){}
};

S sg;                    // Every object of static storage duration is zero initialized at program startup before any other initialization takes place. So 'x' is initialized to 0, before the default constructor runs and sets 'x' to 1.

int main{
   int x = int();        // value initialization syntax, as per rules above is initialized to 0.

    S sl;                // default initialized
}

#7


0  

This is good question. The pletora of c++ type variations makes writing safe templates of the kind as below a pain.

这是很好的问题。c++类型变体的pletora使得编写这种类型的安全模板非常痛苦。

template <typename T> struct FrameworkTemplate {
 T mInstance;
};

Consider that, in theory, the user might instantiate your class template as

考虑到,在理论上,用户可能将类模板实例化为

// assume A is a known default constructible type
FrameworkTemplate<A>
FrameworkTemplate<const A>
FrameworkTemplate<A const *>
FrameworkTemplate<A const &> // and so on

where the last three are not default constructible, though A might be. That's why useful generic types like any, nullable, lazy and so on, though simple and intuitive at the first sight, are non trivial to implement (safely) in c++...

其中最后三个是不可构建的,尽管可能是。这就是为什么有用的泛型类型,如任何可用的、可空的、惰性的等等,尽管乍一看简单且直观,但在c++中实现(安全)并非易事。

#1


11  

Assuming the type is default-constructible, you can use value initialization. For example,

假设类型是默认构造的,可以使用值初始化。例如,

template <typename T>
T get()
{
    return T(); // returns a value-initialized object of type T
}

If the type is not default-constructible, typically you need to provide a default to use. For example,

如果类型不是默认构造的,通常需要提供一个默认值来使用。例如,

template <typename T>
T get(const T& default_value = T())
{
    return default_value;
}

This function can be called with no argument if the type is default-constructible. For other types, you can provide a value to be returned.

如果类型是默认构造的,可以不带参数地调用此函数。对于其他类型,您可以提供要返回的值。

#2


2  

C++ doesn't have the default keyword, because it doesn't have the distinction between reference and value types. In C++, all types are what C# would consider value types, and if they're default constructible (as built-in types, POD structs and class types with default constructors are), they are initialized using value initialization (the default constructor syntax), as James McNellis showed: (and shamelessly copied here)

c++没有默认关键字,因为它没有引用类型和值类型之间的区别。在c++中,所有类型都是c#所考虑的值类型,如果它们是默认的可构造性(如内置类型、POD结构和类类型的默认构造函数),则使用值初始化(默认构造函数语法)来初始化它们,正如James McNellis所展示的那样:(并在此处不加修饰地复制)

template <typename T>
T get()
{
    return T(); // returns a value-initialized object of type T
}

if T has a default constructor, it is invoked. If it has no constructors, everything is initialized to zero/null.

如果T有一个默认构造函数,则调用它。如果没有构造函数,则将所有内容初始化为0 /null。

And if the type is not default constructible, there is no default value the object could be given.

如果类型不是默认可构造的,则不存在对象的默认值。

#3


0  

Use a default constructor, it's used even if you leave off the () at the end:

使用默认构造函数,即使您在结束时省略了(),也会使用它:

#include <iostream>
class MyClass {
    public:
    int x;
    MyClass(){
        x = 5;
    }
};

int main(){
    MyClass y;
    std::cout << y.x;
}

#4


0  

In C++, assigning a default value to a variable in global scope or in a function is as simple as:

在c++中,将一个默认值赋给全局作用域或函数中的一个变量,简单如下:

int myint=2;
float* pfloat=NULL;

For class members, you need to initialise these in the class's constructor:

对于类成员,您需要在类的构造函数中初始化它们:

class myclass {
private:
  int i;
public:
  myclass() {
    i = 4;
  }
};

I'm not sure about structures.

我不确定结构。

#5


0  

In C++, you'd typically invoke the default constructor (the constructor that may be called with no arguments). This works for primitive types too (that is, int() is 0, int*() is the null pointer, etc.).

在c++中,通常会调用默认构造函数(可以不带参数调用的构造函数)。这也适用于基本类型(即int()是0,int*()是空指针,等等)。

For example, in your template function, you'd write something like:

例如,在模板函数中,您可以编写如下内容:

template<typename T>
T foo()
{
    T x = T(); // See notes below about this.

    // Do other stuff.

    return x;
}

Note that T x; by itself would be sufficient to implicitly invoke a default constructor for non-POD types, but that wouldn't work for primitive scalar types (such as int) where it would be initialized to garbage. (T x() also wouldn't work; that would be interpreted as a function declaration.)

注意,T x;它本身就足以隐式地调用非pod类型的默认构造函数,但是对于初始化到垃圾的原始标量类型(比如int)来说,这是行不通的。(T x()也不起作用;这将被解释为函数声明。

#6


0  

Here is a quick summary of initialization techniques in C++03.

下面简要介绍c++ 03中的初始化技术。

To zero-initialize an object of type T means: — if T is a scalar type (3.9), the object is set to the value of 0 (zero) converted to T;

对于零初始化类型为T的对象意味着:-如果T是标量类型(3.9),则将对象设置为转换为T的0(0)的值;

— if T is a non-union class type, each nonstatic data member and each base-class subobject is zeroinitialized;

— if T is a union type, the object’s first named data member89) is zero-initialized;

— if T is an array type, each element is zero-initialized;

— if T is a reference type, no initialization is performed.

To default-initialize an object of type T means:

对于默认初始化的对象类型T意味着:

— if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);

— if T is an array type, each element is default-initialized;

— otherwise, the object is zero-initialized.

To value-initialize an object of type T means: >

对于值初始化的对象,类型T的意思是:>。

— if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);

— if T is a non-union class type without a user-declared constructor, then every non-static data member and base-class component of T is value-initialized;

— if T is an array type, then each element is value-initialized;

— otherwise, the object is zero-initialized

With that understanding

好理解的

struct S{
   int x;
   S():x(1){}
};

S sg;                    // Every object of static storage duration is zero initialized at program startup before any other initialization takes place. So 'x' is initialized to 0, before the default constructor runs and sets 'x' to 1.

int main{
   int x = int();        // value initialization syntax, as per rules above is initialized to 0.

    S sl;                // default initialized
}

#7


0  

This is good question. The pletora of c++ type variations makes writing safe templates of the kind as below a pain.

这是很好的问题。c++类型变体的pletora使得编写这种类型的安全模板非常痛苦。

template <typename T> struct FrameworkTemplate {
 T mInstance;
};

Consider that, in theory, the user might instantiate your class template as

考虑到,在理论上,用户可能将类模板实例化为

// assume A is a known default constructible type
FrameworkTemplate<A>
FrameworkTemplate<const A>
FrameworkTemplate<A const *>
FrameworkTemplate<A const &> // and so on

where the last three are not default constructible, though A might be. That's why useful generic types like any, nullable, lazy and so on, though simple and intuitive at the first sight, are non trivial to implement (safely) in c++...

其中最后三个是不可构建的,尽管可能是。这就是为什么有用的泛型类型,如任何可用的、可空的、惰性的等等,尽管乍一看简单且直观,但在c++中实现(安全)并非易事。