如何在ADL期间使功能模板成为最低优先级?

Jar*_*ock 6 c++ templates argument-dependent-lookup

我有一个问题,我想提供一个函数的泛型版本,foo只有在调用绝对没有其他匹配时才可以应用.我如何修改下面的代码,这样last_resort::foo是更差的比赛derived::typebase::foo?我想找到一个解决方案,它不涉及修改定义, bar而是保留参数的类型last_resort::foo.

#include <iostream>

namespace last_resort
{

template<typename T> void foo(T)
{
  std::cout << "last_resort::foo" << std::endl;
}

}

template<typename T> void bar(T)
{
  using last_resort::foo;
  foo(T());
}

namespace unrelated
{

struct type {};

}

namespace base
{

struct type {};

void foo(type)
{
  std::cout << "base::foo" << std::endl;
}

}

namespace derived
{

struct type : base::type {};

}

int main()
{
  bar(unrelated::type()); // calls last_resort::foo
  bar(base::type());      // calls base::foo
  bar(derived::type());   // should call base::foo, but calls last_resort::foo instead

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

Jar*_*ock 1

last_resort::foo可以用 删除过载设置disable_if。这个想法是禁用last_resort::foo(T)iffoo(T)的其他格式良好。这会导致last_resort::foo(T)最差的匹配foo

namespace test
{

template<typename T> struct has_foo { ... };

}

namespace last_resort
{

template<typename T>
  struct disable_if_has_foo
    : std::enable_if<
        !test::has_foo<T>::value
      >
{};

template<typename T>
  typename disable_if_has_foo<T>::type foo(T)
{
  std::cout << "last_resort::foo" << std::endl;
}

}
Run Code Online (Sandbox Code Playgroud)

输出:

$ g++ last_resort.cpp 
$ ./a.out 
last_resort::foo
base::foo
base::foo
Run Code Online (Sandbox Code Playgroud)

这个答案描述了如何构建一个解决方案来检查是否存在foo返回的函数() void