在C++中标记调度示例

ad3*_*l1s 2 c++ templates

我开始玩这里提供的例子并对其进行修改以获取以下代码:

#include <iostream>

struct slow_tag {}; 
struct fast_tag {};

template <typename T>
struct traits
{
  typedef slow_tag tag;
};

template <>
struct traits<int>
{
  typedef fast_tag tag;
};

template <typename T>
void work_dispatch(const slow_tag)
{
  std::cout << "Slow function" << std::endl;
}

template <typename T>
void work_dispatch(const fast_tag)
{
  std::cout << "Fast function" << std::endl;
}

template <typename T>
void work_dispatch(const T)
{
  work_dispatch(typename traits<T>::tag());
}

int main()
{
  std::cout << "Starting my program" << std::endl;
  work_dispatch(3.0);

  work_dispatch(3);
}
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释为什么这个特定(修改)的例子崩溃与分段错误?如果我编译它,即使使用-Wall与g ++ 4.x,我也不会收到任何类型的警告.

Mar*_* A. 7

我将你的代码简化为一个简单的例子:

#include <iostream>

template <typename T>
void work_dispatch(double)
{
  std::cout << "Slow function" << std::endl;
}

int main()
{
  work_dispatch(3.0);
}
Run Code Online (Sandbox Code Playgroud)

编译错误:

main.cpp:11:3: error: no matching function for call to 'work_dispatch'
  work_dispatch(3.0);
  ^~~~~~~~~~~~~
main.cpp:4:6: note: candidate template ignored: couldn't infer template argument 'T'
void work_dispatch(double)
     ^
1 error generated.
Run Code Online (Sandbox Code Playgroud)

换句话说,您无法调用此模板

template <typename T>
void work_dispatch(double)
{
  std::cout << "Slow function" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

work_dispatch(3.0);
Run Code Online (Sandbox Code Playgroud)

因为你无法推断出类型T,也没有明确地传递它.因此,由于无限递归,您有堆栈溢出:

template <typename T>
void work_dispatch(const T) <----------------|
{                                            | This ends up calling itself
  work_dispatch(typename traits<T>::tag()); -|
}
Run Code Online (Sandbox Code Playgroud)

要修复代码,最简单的解决方案是自己提供类型

template <typename T>
void work_dispatch(const T)
{
  work_dispatch<T>(typename traits<T>::tag());
}
Run Code Online (Sandbox Code Playgroud)

Example