题
C++0x将允许的模板,以采取一个任意数量的参数。什么是最好的使用这一功能比其他的实施组?
解决方案
- 类型安全的printf
- 在工厂方法 中转发任意多个构造函数参数
- 拥有任意基类允许添加和删除有用的政策。
- 通过使用可变参数模板构造函数将异构类型对象直接移动到容器中进行初始化。
- 拥有文字运算符,可以计算用户定义文字的值(例如“10110b”)。 醇>
示例到3:
template<typename... T> struct flexible : T... { flexible(): T()... { } };
示例到4:
struct my_container { template<typename... T> my_container(T&&... t) { } };
my_container c = { a, b, c };
样本到5:
template<char... digits>
int operator "" b() { return convert<digits...>::value; }
请参阅此示例代码:此处
其他提示
- 类安全的
printf
允许像Boost.Function这样的东西采用任意数量的参数
我刚刚写了一篇关于如何实现多个COM接口的文章使用C ++ 0x可变参数模板,您的代码紧凑而优雅。
我已经实现了NDArray(N维数组),它的方法setSizes包含可变参数计数。使用可变参数模板参数比使用可变参数函数参数更安全,而且我只能使用可变参数模板参数控制在编译时传递给此函数的参数计数。
void setSizes(uintmax_t currentSize) {
static_assert(1 == NDimensions, "Invalid count of arguments given to setSizes.");
size_ = currentSize;
data_ = new NDArrayReferenceType[currentSize];
}
template <typename... Sizes>
void setSizes(uintmax_t currentSize, Sizes... sizes) {
static_assert(sizeof...(Sizes) + 1 == NDimensions, "Invalid count of arguments given to setSizes.");
size_ = currentSize;
data_ = new NDArrayReferenceType[currentSize];
for (uintmax_t i = 0; i < currentSize; i++) {
data_[i]->setSizes(sizes...);
}
}
我还为自制的SmartPointer实现了一个通用构造函数包装器。它包装了所有用户定义的原始指针类型的构造函数。
template <typename TSmartPointer, typename... Args>
static inline void initialize(TSmartPointer *smartPointer, Args... args) {
smartPointer->pointer_ = new typename TSmartPointer::PointerType(std::forward<Args>(args)...);
smartPointer->__retain();
}
这段代码似乎不明显,这是SmartPointer的初始化程序的一部分,用于SmartPointer是否应该在获取SmartPointer(RAII)时自动调用指针的构造函数。在抽象类的情况下,它无法调用构造函数。
所以,如果我有一个类型AbstractObject,它是抽象类的SmartPointer,类型为ConcreteObject,它是带有两个整数的构造函数的类的SmartPointer,我可以编写以下代码:
AbstractObject object = ConcreteObject(42, 42);
它就像C#和Java(但使用RAII),它适用于C ++ / GCC 4.8 =)
使用动态参数编号键入每个调用的安全性。
在其他答案中已经提到了类型安全的printf,但更常见的是,可变参数模板可用于实现格式化函数,这些函数根本不需要通过格式说明符传递类型信息。例如, C ++格式库实现类似于Python的格式化函数 str.format :
fmt::print("I'd rather be {1} than {0}.", "right", "happy");
除了安全的printf。使用C ++ 11中的可变参数模板自动捕获参数类型。
这样就不需要像 lld
或臭名昭着的 PRIdPTR
这样的printf说明符而不是
std::printf("Local number: %" PRIdPTR "\n\n", someIntPtr);
可以简单地使用
fmt::printf("Local number: %d\n\n", someIntPtr);
免责声明:我是这个图书馆的作者