调用静态方法

时间:2014-08-20 08:56:14

标签: c++ templates

我最近遇到的代码看起来像这样

template <typename T>
void Foo()
{
    T::Bar();
}

我很困惑,这是怎么编的?在C#泛型中对T没有约束。

我意识到模板不像泛型,因为前者基本上是美化的宏,所以就是这样的情况就是Foo的每个用法都是针对该实例中提供的T进行编译的,并且给出了它有Bar()功能吗?有点像鸭子打字?

这是自c ++ 03以来它是如何工作的,还是c ++ 11中的新东西?

3 个答案:

答案 0 :(得分:3)

这个模板函数只强制在替换类型T时,表达式T::Bar();是有效的,只要它有效,它就会编译(在C ++中没有类似C#的约束):

以下是使用模板的两个示例:

#include <iostream>
#include <functional>

struct X
{
    static void Bar() { std::cout << "Bar X\n!"; }
};

struct Y
{
    static std::function<void(void)> Bar;
};

std::function<void(void)> Y::Bar = []() { std::cout << "Bar Y!"; };

template <typename T>
void Foo()
{
    T::Bar();
}


int main()
{
    Foo<X>();
    Foo<Y>();
    return 0;
}

答案 1 :(得分:2)

模板仅在实例化时编译,即通过执行

Foo<int>();

在这种情况下,通过用T替换你传入的具体类型来生成实际代码(这当然会导致编译错误,因为int没有静态成员函数{{ 1}})。

这是设计上的,并且一直存在。

答案 2 :(得分:2)

这就是模板的工作方式和工作方式,C ++ 11中没有什么新东西。如果T::Bar()对于给定类型有效,它会编译,所以它就像你说的那样打字。大多数C ++标准库基于这个原理工作 - 例如迭代器需要operator*才能工作,如果你有自己的迭代器,它们将使用标准算法,前提是你实现了这个操作符(以及基于迭代器类别所需的其他操作)。您不需要以任何其他方式指定迭代器 - 只需提供所需的操作。