【问题标题】:C++ template partial specialization by a function of pointer / a function of const pointer are not different?C++模板部分特化由一个指针函数/一个const指针函数没有区别吗?
【发布时间】:2015-12-14 11:48:33
【问题描述】:

让我们考虑以下代码:

template <typename T>
class Foo
{};

template <typename T, typename U>
class Foo<T(*)(U* const)>
{};

template <typename T, typename U>
class Foo<T(*)(U*)>
{};

当我尝试编译它(ideone) 时,它无法告诉我这两个模板特化是相同的。这令人惊讶,因为通常 U*U* const 是不同的东西(第二个是 const 指针)。这里有什么问题?

【问题讨论】:

  • 签名相同。函数参数的顶级限定符从签名中默默地删除。也许你想要U const *
  • @n.m.它们并没有什么不同:我可以做 Foo&lt;U* const&gt;Foo&lt;U*&gt; 专业化就好了。实际上我想要U const *U * const(以及U const * const)。
  • U*U* const的类型不同,但T(U*)T(U* const)是一样的。您不能重载它们,因为它们是相同的签名。目前还不清楚这可能有什么用途。这与重载int func(int)int func(const int) 相同。干什么用的?
  • 只是为了说明:即使没有模板,您也不能同时拥有void foo(int)void foo(const int)。这是一个错误:error: redefinition of 'void foo(int)'
  • 通过参数的常量重载没有意义。但这与函数重载无关,不是吗?我想为两个不同的功能(具有不同的名称)使用两种不同的专业化。

标签: c++ templates constants function-pointers


【解决方案1】:

当确定一个函数的类型(通俗地称为它的签名)时,顶级 cv 限定符被丢弃。

§8.3.5/5 ... 函数的类型使用以下方法确定 规则。 ...在生成参数类型列表后,任何顶级 修改参数类型的 cv 限定符在形成 函数类型。 ...

对于使 this 无效的函数指针或模板参数没有特殊规则。

【讨论】:

    【解决方案2】:

    你必须这样写:

    template <typename T, typename U>
    class Foo<T(*)(const U* )>
    {};
    

    【讨论】:

    • 你不能命名任何东西const。这是一个保留字。
    • 这不是我想要的。
    猜你喜欢
    • 2011-08-24
    • 1970-01-01
    • 2021-12-08
    • 1970-01-01
    • 2020-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-04
    相关资源
    最近更新 更多