【问题标题】:Template code won't compile (Deferred lookup)模板代码无法编译(延迟查找)
【发布时间】:2011-11-20 20:18:56
【问题描述】:

我有两个奇怪的情况,看起来代码应该编译,但事实并非如此。首先,考虑下面的代码,它编译成功:

struct A
{
    template <class T>
    void member_func(T t)
    {
        global_func(t);
    }
};

int main()
{
}

但如果我通过前缀“::”来完全限定 global_func,它不会编译并出现错误“'global_func' is not declared in this scope”:

struct A
{
    template <class T>
    void member_func(T t)
    {
        ::global_func(t);
    }
};

int main()
{
}

另外,如果我尝试将 global_func 传递给 boost::bind,它不会编译(同样的错误):

#include <boost/bind.hpp>

class A
{
    template <class T>
    void member_func(T t)
    {
        boost::bind(global_func)(t);
    }
};

int main()
{
}

为什么在这些情况下它不能编译?好像 member_func() 模板方法没有被实例化,所以它不应该找到缺少的函数错误。

【问题讨论】:

  • 你不需要这样的代码:void global_func(int a);无效 global_func(float b);等等?
  • 您的第一个和第二个示例是相同的,您可能需要编辑。
  • @tp1 - 据我了解 - 不。这个想法是,模板在需要时被实例化。并且由于没有人实例化这个模板函数(例如——调用这个成员函数或创建的对象A),所以应该没有编译错误。
  • 有趣。我明白为什么 ::global_func 不会被视为“取决于模板参数”,但 bind 样本应该等同于第一个
  • @themel 好像有人帮我修好了,谢谢!

标签: c++ templates compilation


【解决方案1】:

在第一个示例中,global_func 是一个从属名称,因为它是在后缀 () 表达式中使用的非限定名称,其中括号中的表达式取决于模板参数。这意味着必须将查找推迟到模板被实例化时模板参数已知并且 ADL 可能会产生影响。

在第二个示例中,::global_func 是一个限定名称,因此它的查找不会延迟,并且必须在定义模板的指针处查找。

类似地,在表达式 boost::bind(global_func) 中,global_func 不用于依赖于模板参数的表达式,因此,再次查找不会延迟,并且声明必须在成员模板的定义点可见.

【讨论】:

  • 感谢您的精彩回答!快速跟进:是否有强制延迟查找的常用技巧?
  • @redmoskito:对于您的情况,我不知道任何常见的,但是我不知道您期望global_func 拥有什么类型。如果您能够限制global_func 的类型,则可以使用“no-op”强制转换。例如static_cast&lt;void(*)(T)&gt;(global_func) 或类似的东西,但这可能会影响模板的行为。
猜你喜欢
  • 2014-03-13
  • 1970-01-01
  • 1970-01-01
  • 2019-05-29
  • 1970-01-01
  • 2016-07-08
  • 2017-01-16
  • 1970-01-01
相关资源
最近更新 更多