在讨论“隐藏功能”问题时,没有关于C++的爱吗?我想我应该提出这个问题。C++有哪些隐藏功能?
在讨论“隐藏功能”问题时,没有关于C++的爱吗?我想我应该提出这个问题。C++有哪些隐藏功能?
本地类很棒:
struct MyAwesomeAbstractClass
{ ... };
template <typename T>
MyAwesomeAbstractClass*
create_awesome(T param)
{
struct ans : MyAwesomeAbstractClass
{
// Make the implementation depend on T
};
return new ans(...);
}
非常整洁,因为它不会使用无用的类定义污染命名空间...
Fred* f = new(ram) Fred(); http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.10
f->~Fred();
我最喜欢的秘密技巧是很少被使用的:
class A
{
};
struct B
{
A a;
operator A&() { return a; }
};
void func(A a) { }
int main()
{
A a, c;
B b;
a=c;
func(b); //yeah baby
a=b; //gotta love this
}
即便是对于GCC开发人员来说都不为人知的一个隐藏功能是可以使用字符串字面量来初始化数组成员。假设您有一个需要使用C数组进行工作的结构体,并且您想将数组成员初始化为默认内容。
struct Person {
char name[255];
Person():name("???") { }
};
这个方法只适用于字符数组和字符串字面值初始化,不需要使用 strcpy
方法!
void foo(){char p[255] = "daddy";}
也是初始化数组的一种合法方式,这似乎很明显。 - P Daddy="foo"
,但几乎从未用于成员初始化。在我读标准并发现它被允许并与其他编译器一起工作之前,我从未见过它。 - Johannes Schaub - litbclass C{char p[255] = "daddy";};
这样的东西后,下一个想到的就是“只有静态常量整型数据成员才能用类初始化”。但当时,我刚刚学习了初始化列表,所以可能更容易理解。无论如何,这绝对是一个清晰的例子,说明初始化列表与构造函数体内的赋值是不同的。 - P Daddy原始类型有构造函数。
int i(3);
工作正常。
模板元编程并不是一个隐蔽的特性,甚至在boost库中都有。请参阅MPL。但如果“几乎隐藏”的足够好,那么可以看看boost libraries。它包含许多好东西,但如果没有强大的库支持,这些好东西并不容易访问。
一个例子是boost.lambda库,这很有趣,因为C++当前标准中没有lambda函数。
另一个例子是Loki,它“广泛使用C++模板元编程,并实现了几个常用工具:类型列表、函数对象、单例、智能指针、对象工厂、访问者和多方法。”[维基百科]没有隐藏的功能,但C++语言非常强大,甚至连标准的开发人员也无法想象C++可以用于什么。
实际上,从足够简单的语言结构中,您可以编写一些非常强大的东西。许多这样的内容可以在www.boost.org上作为示例找到(其中包括http://www.boost.org/doc/libs/1_36_0/doc/html/lambda.html)。
要理解如何将简单的语言结构组合成强大的东西,最好阅读David Vandevoorde和Nicolai M. Josuttis的《C++ Templates: The Complete Guide》以及真正神奇的书《Modern C++ Design ... 》by Andrei Alexandrescu。
最后,学习C++很困难,您应该尝试填补它;)
我觉得只有少数人知道未命名命名空间:
namespace {
// Classes, functions, and objects here.
}
未命名的命名空间表现得好像它们被替换为:
namespace __unique_name__ { /* empty body */ }
using namespace __unique_name__;
namespace __unique_name__ {
// original namespace body
}
"..在一个翻译单元中,所有出现的 [这个唯一名称] 都被替换为相同的标识符,而且这个标识符与整个程序中的所有其他标识符都不同。" [C++03, 7.3.1.1/1]
来自C++ Truths。
在同一作用域内定义具有相同签名的函数是合法的:
template<class T> // (a) a base template
void f(T) {
std::cout << "f(T)\n";
}
template<>
void f<>(int*) { // (b) an explicit specialization
std::cout << "f(int *) specilization\n";
}
template<class T> // (c) another, overloads (a)
void f(T*) {
std::cout << "f(T *)\n";
}
template<>
void f<>(int*) { // (d) another identical explicit specialization
std::cout << "f(int *) another specilization\n";
}