【问题标题】:Need help to understand the purpose of a following class需要帮助以了解以下课程的目的
【发布时间】:2015-03-27 13:59:32
【问题描述】:

我的朋友给我发了一个有趣的任务:

template<typename T>
class TestT
{
public:
    typedef char ONE;
    typedef struct { char a[2]; } TWO;

    template<typename C>
    static ONE test(int C::*);

    template<typename C>
    static TWO test(...);
public:
    enum{ Yes = sizeof(TestT<T>::template test<T>(0)) == 1 };
    enum{ No = !Yes };
};

我无法用 VS2013 编译这段代码。使用 GCC 4.9.0 可以编译。但我不明白它的作用。

我的兴趣点:

  1. 如果函数只有声明而没有定义,它如何工作?
  2. TestT&lt;T&gt;::template test&lt;T&gt;(0) 是什么?它看起来像一个函数调用。
  3. ::template 是什么意思?
  4. 以上课程的目的是什么?
  5. 用到的原理怎么叫?
  6. int C::* 是指向 int 成员的指针,对吧?

【问题讨论】:

  • 吟唱 向伟大的老者致敬 SFINAE!

标签: c++ templates


【解决方案1】:
  1. 它实际上并不调用函数,它只是查看返回类型的sizeof 是什么。
  2. 一个函数调用。见下文。
  3. template 是必需的,因为 dependent type 问题。
  4. 它测试是否有指向类型参数数据成员的指针。这仅适用于 类类型(例如,std::string,但不适用于 int)。您可以在 is_class 的名称下找到类似 for example here 的代码,其中包含与您的示例非常相似的内容。
  5. SFINAE,代表“替换失败不是错误”。一旦您意识到用C 替换int 将失败并因此简单地导致其中一个函数重载不存在(而不是导致编译器错误并中止编译),这个名称的原因就变得显而易见了。
  6. 是的,它是指向C 类型对象内部的int 的指针。

【讨论】:

  • 谢谢!太棒了!
【解决方案2】:

对于一个问题来说,问题太多了,但是:

  1. sizeof 不计算其操作数,它只确定类型。这不需要定义操作数调用的任何函数 - 类型由声明确定。

  2. 是的,这是一个函数调用。如果类和函数不是模板,它看起来像TestT::test(0)

  3. template 是必需的,因为名称 test 的含义取决于类模板参数,如 Where and why do I have to put the "template" and "typename" keywords? 中所述。

  4. 它定义了一个常量Yes,如果T 是一个类类型则为1,否则为0。也是一个常量No,具有逻辑反转的值。

  5. 看起来它打算在SFINAE 中使用,以允许模板部分专用于类和非类类型。从 C++11 开始,我们可以为此使用标准特征,例如 std::is_class

  6. 是的,如果 C 是类类型。否则,这是一个类型错误,因此采用该类型的重载将被忽略,只留下第二个重载。因此,如果C 是类类型,test 的返回类型为ONE(大小为一),否则TWO(大小为二);因此sizeof(...) == 1 的测试区分类和非类类型。

【讨论】:

    猜你喜欢
    • 2013-10-27
    • 2018-10-10
    • 2021-11-18
    • 1970-01-01
    • 2019-07-08
    • 2017-04-18
    • 2017-06-19
    • 2016-05-03
    • 1970-01-01
    相关资源
    最近更新 更多