c++ - 基于非成员函数的参数进行调度

标签 c++ polymorphism dispatch

我当时(可能不正确)假设 C++ 中的非成员函数不会根据其参数类型进行分派(dispatch)。但是在阅读了 iterator_category 之后,我似乎可以根据其参数的类别类型调用一个函数,并且该调用还处理继承。例如,如果我只编写随机访问迭代器和输入迭代器的实现,所有使用非随机访问迭代器的调用都将转到接受输入迭代器的函数。这是书中的一个简短示例

template <class T>
foo(T a) {
  foo(a, iterator_traits<T>::iterator_category());
}

template <class T>
foo(T a, random_access_iterator_tag) { \\body}

template <class T>
foo(T a, input_iterator_tag) { \\body}

// presumably this works even for
// ostream_iterator<int> i(cout);
// foo(i);

这种调度是普遍正确的还是特例?

如果我的实现不详尽,编译器是否应该警告我,例如在基于迭代器类别的示例中,如果我只给出了随机访问迭代器和双向迭代器的实现,编译器是否应该提示未涵盖输出迭代器.

这也是我第一次遇到参数只是类型而不是对象/实例的函数。那么我是否可以将具有内置或用户定义类型的函数定义为其参数之一而不指定该类型的实例/对象的名称?

下面似乎是CRTP的替代方案,实现编译时多态性。这是正确的解释吗

template<class T>
int foo(T a) {
  foo(a, a::type());
}

int foo(int a, base) { \\body }
int foo(int a, derived) { \\body }

最佳答案

重载函数调用通过参数的static 类型来解析(这对于成员函数和非成员函数都是如此)。

所以:

class Base {};
class Derived : public Base {};

void foo(Base &b) {}
void foo(Derived &d) {}

Base b;
Derived d;
Base &r = d;

foo(b);  // Calls first overload
foo(d);  // Calls second overload
foo(r);  // Calls first overload

更新

因此在您的新代码片段中,参数不是类型,它们只是“匿名的”;它们没有关联的变量名。

这一切都在编译时解决。 iterator_traits<T>::iterator_category是一个 typedef(它将通过 T 模板依赖于 iterator_traits<T>)。 iterator_traits<T>::iterator_category()正在调用构造函数,以创建该类型的新临时对象,该对象用作“虚拟”参数。然后编译器将该调用解析为正确的重载。鉴于此参数是一个虚拟参数,因此函数内不需要变量名。

关于c++ - 基于非成员函数的参数进行调度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7414770/

相关文章:

zend-framework - 如何在 Zend PHPUnit Controller 测试中调度带有子域的 url?

java - Java 编译时参数分配是否损坏?

c++ - 是否修改 const 对象的内部字节未定义行为,以防它包含由放置 new 构造的另一个对象?

c++ - 如何在不相关类型的共享指针中共享相同的引用计数器?

c++ - C++中多态对象的二维容器

c# - 多态,调用父类的子方法

java - Java 中的多态性和 ArrayList

java - 基于字符串的调度,无需反射或在多个位置编写代码

c++ - 使用英特尔 AVX 通过掩码改组

C++ : Difference between linking library and adding include directories