【问题标题】:Parameterize functions with classes and access class members使用类参数化函数并访问类成员
【发布时间】:2019-01-28 14:21:00
【问题描述】:

我想知道这段代码具体是如何工作的(例如,它如何能够直接访问 TYPE 的值)。

我在一个更大的代码库中看到了这段代码(它是非公开的,所以这个例子被解释了)。我从未见过这种特定的用例。传递这样的模板参数很常见吗?它有一个特定的名称/这是一个成语/模式吗?你什么时候会用这个,为什么?

#include <iostream>

namespace FileA
{
struct Foo
{
    enum TYPE
    {
        ENTRY,
    };

    void callme()
    {
        std::cout << "Foo\n";
    }
};
}

namespace FileB
{
template <typename T>
void fun(T& obj)
{
    std::cout << T::ENTRY << "\n";
    obj.callme();
}
}

int main()
{
    FileA::Foo f;
    FileB::fun(f);
}

这将打印:

0
Foo

【问题讨论】:

  • 很难说你的问题是什么......这是一个模板函数,它访问给定对象/类型的成员。只有当这些成员存在时才会编译。这就是模板应该表现的所有方式,并且像这样使用它们并不少见......
  • 基本上,删除template&lt;&gt; 的东西并将T 替换为FileA::Foo。产生的任何代码和行为是否让您感到惊讶?如果是,那与模板无关。如果不是,上述替换就是编译器为实例化模板所做的全部工作。
  • @user463035818 在枚举定义中尾随,definitely ok
  • @MaxLanghof 嗯好的,那么我今天已经学到了一些东西。而且,对不起@ OP ;)
  • 你的问题不太清楚,这个“成语”没有名字。实际上不清楚你认为这段代码有什么特别之处,它值得一个名字,也许你可以解释更多? “传递这样的模板参数很常见吗?” 否则您将如何传递模板参数?

标签: c++ function templates parameters


【解决方案1】:

模板是术语一般意义上的一种宏,所以如果你“扩展” FileB::fun(f); T 被替换为 f 的类型FileA::Foo 就像你有:

void fun(FileA::Foo& obj)
{
    std::cout << FileA::Foo::ENTRY << "\n";
    obj.callme();
}

因为 FileA::Foo::ENTRY 是 0,std::cout 写入 0,然后你应用 FileA::Foo::callme() 打印 Foo

警告,模板远不止于此,它只是对该示例如何工作和产生输出的非常简化的解释,请不要按字面意思理解它^^

【讨论】:

  • 不清楚这个问题是否也与此有关,但由于“像这样传递模板参数”的措辞,我还要说几句话关于模板参数推导......
  • @MaxLanghof 只是为不知道模板是什么的人解释的一种方式,请不要把这个放在信的末尾^^
  • "是一种宏" 我想我知道你的意思,但读到这里还是有点疼:P。我想说最重要的区别是编译器知道模板,但对宏一无所知
  • @user463035818 预处理器不是编译器的一部分吗?
  • @user463035818 如果您的编译器无法帮助您跟踪从宏生成的代码,您可能需要切换/升级编译器。不要误会我的意思,他们不能神奇地去混淆深层嵌套的宏,但basic troubleshooting 绝对是有可能的。
猜你喜欢
  • 2019-10-16
  • 2012-10-08
  • 1970-01-01
  • 2021-03-25
  • 1970-01-01
  • 2017-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多