C++的隐藏特性?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/75538/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 12:40:20  来源:igfitidea点击:

Hidden Features of C++?

c++hidden-features

提问by Craig H

No C++ love when it comes to the "hidden features of" line of questions? Figured I would throw it out there. What are some of the hidden features of C++?

当涉及到“隐藏特性”的问题时,没有 C++ 爱吗?想我会把它扔在那里。C++ 有哪些隐藏的特性?

回答by Ferruccio

Most C++ programmers are familiar with the ternary operator:

大多数 C++ 程序员都熟悉三元运算符:

x = (y < 0) ? 10 : 20;

However, they don't realize that it can be used as an lvalue:

但是,他们没有意识到它可以用作左值:

(a == 0 ? a : b) = 1;

which is shorthand for

这是简写

if (a == 0)
    a = 1;
else
    b = 1;

Use with caution :-)

谨慎使用:-)

回答by Ben

You can put URIs into C++ source without error. For example:

您可以将 URI 放入 C++ 源代码中而不会出错。例如:

void foo() {
    http://stackoverflow.com/
    int bar = 4;

    ...
}

回答by Ben

Pointer arithmetics.

指针算术。

C++ programmers prefer to avoid pointers because of the bugs that can be introduced.

C++ 程序员更喜欢避免使用指针,因为可能会引入错误。

The coolest C++ I've ever seen though? Analog literals.

我见过的最酷的 C++ 是什么?模拟文字。

回答by paercebal

I agree with most posts there: C++ is a multi-paradigm language, so the "hidden" features you'll find (other than "undefined behaviours" that you should avoid at all cost) are clever uses of facilities.

我同意那里的大多数帖子:C++ 是一种多范式语言,因此您会发现的“隐藏”功能(除了您应该不惜一切代价避免的“未定义行为”)是对设施的巧妙使用。

Most of those facilities are not build-in features of the language, but library-based ones.

这些工具中的大多数都不是该语言的内置功能,而是基于库的功能。

The most important is the RAII, often ignored for years by C++ developers coming from the C world. Operator overloadingis often a misunderstood feature that enable both array-like behaviour (subscript operator), pointer like operations (smart pointers) and build-in-like operations (multiplying matrices.

最重要的是RAII,多年来经常被来自 C 世界的 C++ 开发人员忽略。运算符重载通常是一个被误解的特性,它支持类似数组的行为(下标运算符)、类似指针的操作(智能指针)和类似内置的操作(乘法矩阵)。

The use of exceptionis often difficult, but with some work, can produce really robust code through exception safetyspecifications (including code that won't fail, or that will have a commit-like features that is that will succeed, or revert back to its original state).

异常的使用通常很困难,但是通过一些工作,可以通过异常安全规范生成真正健壮的代码(包括不会失败的代码,或者将具有类似提交的功能,即会成功,或恢复到其原始状态)。

The most famous of "hidden" feature of C++ is template metaprogramming, as it enables you to have your program partially (or totally) executed at compile-time instead of runtime. This is difficult, though, and you must have a solid grasp on templates before trying it.

C++ 最著名的“隐藏”特性是模板元编程,因为它使您能够在编译时而不是运行时部分(或完全)执行您的程序。但是,这很困难,在尝试之前,您必须对模板有一个扎实的掌握。

Other make uses of the multiple paradigm to produce "ways of programming" outside of C++'s ancestor, that is, C.

其他人利用多重范式在 C++ 的祖先(即 C)之外产生“编程方式”。

By using functors, you can simulate functions, with the additional type-safety and being stateful. Using the commandpattern, you can delay code execution. Most other design patternscan be easily and efficiently implemented in C++ to produce alternative coding styles not supposed to be inside the list of "official C++ paradigms".

通过使用functors,您可以模拟具有额外类型安全性和有状态的函数。使用命令模式,您可以延迟代码执行。大多数其他设计模式可以在 C++ 中轻松有效地实现,以生成不应该在“官方 C++ 范式”列表中的替代编码样式。

By using templates, you can produce code that will work on most types, including not the one you thought at first. You can increase type safety,too (like an automated typesafe malloc/realloc/free). C++ object features are really powerful (and thus, dangerous if used carelessly), but even the dynamic polymorphismhave its static version in C++: the CRTP.

通过使用模板,您可以生成适用于大多数类型的代码,包括您最初想到的类型。您也可以提高类型安全性(例如自动类型安全 malloc/realloc/free)。C++ 对象特性非常强大(因此,如果不小心使用,会很危险),但即使是动态多态性在 C++ 中也有它的静态版本:CRTP

I have found that most "Effective C++"-type books from Scott Meyers or "Exceptional C++"-type books from Herb Sutter to be both easy to read, and quite treasures of info on known and less known features of C++.

我发现大多数来自 Scott Meyers 的“ Effective C++”类书籍或来自 Herb Sutter 的“ Exceptional C++”类书籍都易于阅读,并且包含了有关 C++ 已知和鲜为人知的特性的大量信息。

Among my preferred is one that should make the hair of any Java programmer rise from horror: In C++, the most object-oriented way to add a feature to an object is through a non-member non-friend function, instead of a member-function(i.e. class method), because:

在我的首选中,应该让任何 Java 程序员的头发从恐惧中升起:在 C++ 中,向对象添加功能的最面向对象的方法是通过非成员非友元函数,而不是成员 -函数(即类方法),因为:

  • In C++, a class' interface is both its member-functions and the non-member functions in the same namespace

  • non-friend non-member functions have no privileged access to the class internal. As such, using a member function over a non-member non-friend one will weaken the class' encapsulation.

  • 在 C++ 中,类的接口既是它的成员函数又是同一命名空间中的非成员函数

  • non-friend 非成员函数没有特权访问类内部。因此,在非成员非友元函数上使用成员函数会削弱类的封装性。

This never fails to surprise even experienced developers.

即使是经验丰富的开发人员,这也永远不会让您感到惊讶。

(Source: Among others, Herb Sutter's online Guru of the Week #84: http://www.gotw.ca/gotw/084.htm)

(来源:除其他外,Herb Sutter 的本周在线大师 #84:http: //www.gotw.ca/gotw/084.htm

回答by Jason Mock

One language feature that I consider to be somewhat hidden, because I had never heard about it throughout my entire time in school, is the namespace alias. It wasn't brought to my attention until I ran into examples of it in the boost documentation. Of course, now that I know about it you can find it in any standard C++ reference.

我认为有些隐藏的语言功能是命名空间别名,因为我在整个学校期间从未听说过它。直到我在 boost 文档中遇到它的例子后才引起我的注意。当然,既然我知道它,您可以在任何标准 C++ 参考中找到它。

namespace fs = boost::filesystem;

fs::path myPath( strPath, fs::native );

回答by Johannes Schaub - litb

Not only can variables be declared in the init part of a forloop, but also classes and functions.

不仅可以在for循环的 init 部分声明变量,还可以在类和函数中声明。

for(struct { int a; float b; } loop = { 1, 2 }; ...; ...) {
    ...
}

That allows for multiple variables of differing types.

这允许不同类型的多个变量。

回答by Colin Jensen

The array operator is associative.

数组运算符是关联的。

A[8] is a synonym for *(A + 8). Since addition is associative, that can be rewritten as *(8 + A), which is a synonym for..... 8[A]

A[8] 是 *(A + 8) 的同义词。由于加法是结合的,所以可以改写为 *(8 + A),它是..... 8[A] 的同义词

You didn't say useful... :-)

你没有说有用... :-)

回答by Johannes Schaub - litb

One thing that's little known is that unions can be templates too:

鲜为人知的一件事是联合也可以是模板:

template<typename From, typename To>
union union_cast {
    From from;
    To   to;

    union_cast(From from)
        :from(from) { }

    To getTo() const { return to; }
};

And they can have constructors and member functions too. Just nothing that has to do with inheritance (including virtual functions).

它们也可以有构造函数和成员函数。与继承无关(包括虚函数)。

回答by Konrad Rudolph

C++ is a standard, there shouldn't be any hidden features...

C++ 是一个标准,不应该有任何隐藏的功能......

C++ is a multi-paradigm language, you can bet your last money on there being hidden features. One example out of many: template metaprogramming. Nobody in the standards committee intended there to be a Turing-complete sublanguage that gets executed at compile-time.

C++ 是一种多范式语言,您可以将最后一笔钱押在隐藏功能上。众多示例中的一个:模板元编程。标准委员会中没有人打算有一种在编译时执行的图灵完备子语言。

回答by Johannes Schaub - litb

Another hidden feature that doesn't work in C is the functionality of the unary +operator. You can use it to promote and decay all sorts of things

另一个在 C 中不起作用的隐藏特性是一元运算+符的功能。你可以用它来促进和衰减各种事物

Converting an Enumeration to an integer

将枚举转换为整数

+AnEnumeratorValue

And your enumerator value that previously had its enumeration type now has the perfect integer type that can fit its value. Manually, you would hardly know that type! This is needed for example when you want to implement an overloaded operator for your enumeration.

以前具有枚举类型的枚举器值现在具有可以适合其值的完美整数类型。手动,你几乎不会知道那种类型!例如,当您想为枚举实现重载运算符时,就需要这样做。

Get the value out of a variable

从变量中获取值

You have to use a class that uses an in-class static initializer without an out of class definition, but sometimes it fails to link? The operator may help to create a temporary without making assumptins or dependencies on its type

您必须使用一个使用类内静态初始化程序而没有类外定义的类,但有时它无法链接?操作符可以帮助创建一个临时的,而不需要对其类型进行假设或依赖

struct Foo {
  static int const value = 42;
};

// This does something interesting...
template<typename T>
void f(T const&);

int main() {
  // fails to link - tries to get the address of "Foo::value"!
  f(Foo::value);

  // works - pass a temporary value
  f(+Foo::value);
}

Decay an array to a pointer

将数组衰减为指针

Do you want to pass two pointers to a function, but it just won't work? The operator may help

您是否想将两个指针传递给一个函数,但它不起作用?运营商可能会帮忙

// This does something interesting...
template<typename T>
void f(T const& a, T const& b);

int main() {
  int a[2];
  int b[3];
  f(a, b); // won't work! different values for "T"!
  f(+a, +b); // works! T is "int*" both time
}