【问题标题】:Delegate nullptr parameter to the pointer overload in template code将 nullptr 参数委托给模板代码中的指针重载
【发布时间】:2015-11-19 23:01:10
【问题描述】:

考虑下面的代码:

#include <iostream>

template<typename T> // generic
void f(T)
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}

template<typename T> // overload for pointer types
void f(T*)
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}

int main()
{
    int* p{nullptr};
    f(p);       // correct delegation to f<T*>();
    f(nullptr); // calls f<T>();
}

Live on Coliru

如您所见,调用f(nullptr) 会导致调用泛型f(T),而不是指针重载f(T*)。这很烦人。我知道为什么会这样:因为nullptrstd::nullptr_t 类型,并且泛型模板具有更高的重载等级。

我怎样才能以直接的方式“解决”这个问题?我当然可以编写两种不同的实现,一种用于指针,一种用于nullptr_t,然后有一个通用的实现,通过一些 SFINAE 分派到两者之一,但这看起来有点太复杂了。

【问题讨论】:

  • std::nullptr_t 没有指向的类型时,你怎么能期望T* 重载被调用?我认为无论如何您确实需要针对这种情况使用单独的逻辑,因此您不妨添加第三个重载。
  • @Brian 我不希望f(T*) 被调用,我想轻松获得这种行为。
  • 当您致电f(T*) 时,您期望T 是什么?
  • 我的意思是@cicto 所说的。谢谢你说得比我好。
  • 哦,我明白你的意思了......这确实是一个我没有想到的好点。所以看起来第三个重载是要走的路。

标签: c++ templates c++11 nullptr


【解决方案1】:

最简单的方法可能是实现一个重载void f(std::nullptr_t),然后分派给一个指针实现,你可以选择它,假设它对空指针做了正确的事情(无论正确的事情是什么):

void f(std::nullptr_t) { f(static_cast<void *>(nullptr)); }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-28
    • 2015-11-04
    • 2011-04-11
    相关资源
    最近更新 更多