如何在编译时选择方法
How to select the method at compilation time?
我记得读过一些文章,使用新的C++功能在编译器时实现选择,但不知道该怎么做。例如,我有一个执行以下操作的方法
template<class T>
void foo()
{
if (std::is_abstract<T>::value)
do something;
else
do others.
}
编译时决策通常通过重载选择来完成。
void foo_impl(std::true_type) {
do something;
}
void foo_impl(std::false_type) {
do others.
}
template<class T>
void foo()
{
foo_impl(std::is_abstract<T>());
}
如果两个分支都编译,上面的代码实际上是可以的,并将在编译时进行选择:编译器将检测到一个分支已死并且永远不会使用。优化时,没有自尊的编译器会使用分支。
特别是当分支可能无法根据类型进行编译时,您可以使用 std::enable_if
有条件地使重载可用:
template <typename T>
typename std::enable_if<std::is_abstract<T>::value>::type foo()
{
do something
}
template <typename T>
typename std::enable_if<!std::is_abstract<T>::value>::type foo()
{
do other
}
std::is_abstract
实用程序是类型特征的一个例子,我喜欢遵循经典的选择器习语:
#include<iostream>
#include<type_traits>
template<bool>
struct algorithm_selector {
static void implementation() {
std::cout<<"I am using the default implementation"<<std::endl;
}
};
template<>
struct algorithm_selector<true> {
static void implementation() {
std::cout<<"I am using the 'custom' implementation"<<std::endl;
}
};
template<typename T>
void foo() {
algorithm_selector<std::is_abstract<T>::value>::implementation();
}
struct ABC { virtual void bar() const = 0; };
struct Derived : ABC { };
struct Blah {};
int main() {
foo<ABC>();
foo<Derived>();
foo<Blah>();
return 0;
}
编译为 (gcc 4.8.1) g++ example.cpp -std=c++11
产生输出:
I am using the 'custom' implementation
I am using the 'custom' implementation
I am using the default implementation
我喜欢它的是它超越了*enable_if*的基本原理(至少在概念上):它为我提供了可用于在编译时选择任意策略的习语。这可能只是一个偏好问题,但对我来说,这个成语是坚如磐石的。另外,请查看安德烈·亚历山德雷斯库书中描述的政策模式;它们与这种由编译时功能驱动的设计灵活性有关。
相关文章:
- 在PostgreSQL中根据它们的ID选择大量行的最快方法是什么?
- 从长(且合理)稀疏向量中选择随机元素的最有效方法是什么?
- 基于类实例的自动方法选择
- 模板类中的动态模板方法选择
- 我将如何通过抽象类传递虚拟方法,但可以选择不重写
- 根据编译时条件在类型之间选择类型的惯用方法
- 通过方法返回的重新选择参考
- 有没有一种方法可以在基于枚举的可变参数模板函数之间进行选择,这比将函数包装在结构中更简单
- 根据输入类型选择正确的结构方法
- 有什么方法可以让用户选择要输入哪个变量
- 为什么我们选择"bounding box"方法来填充三角形?
- 在Boost Graph库中选择给定顶点的随机进出邻居的有效方法
- 在游戏地图上选择100种情况的最佳方法(MFC,CPoint)
- C++模板方法选择正确的数据打印方式
- 选择正确功能的更好方法
- 如何使用模板参数选择方法调用
- 如何在编译时选择方法
- 在运行时选择方法实现
- 如何让编译器为派生类选择方法的非模板版本
- 如何在从QVariant参数转换时选择方法重载