不使用模板参数的函数使过多的代码膨胀?

Excess code bloat by function that doesn't use template parameters?

本文关键字:代码 膨胀 函数 参数      更新时间:2023-10-16

我有一个函数 f,它接受一个 Bar 类型的参数,它有 3 个模板参数。 f 不使用这三个参数中的任何一个。 问题:编译器是否仍然根据 A、B 和 C 的所有使用组合生成多个版本的 f,或者是否有更好的方法来执行此操作?

例:

template<typename A, typename B, typename C>
class Bar;
template<typename A, typename B, typename C>
void f(Bar<A,B,C>& bar)
{
  //code that does not use A, B or C, e.g.:
  std::cout << bar.some_getter() << std::endl;
}

编译器是否真的会生成不同的代码(或者首先生成任何单独的代码)将取决于您对这些函数执行的操作。例如,如果您只是调用函数并且它相当小,编译器可能会完全内联代码,使其可能比最初创建函数时更小。

另一方面,如果你采用不同实例化的地址,它们将具有不同的地址,即,即使编译器可能共享许多相同的代码,如果类型相同,它也需要具有不同的地址。我不确定您是否可以比较不同类型的函数指针(随着参数Bar<A, B, C>的变化,我们的函数将具有不同的类型)。

请注意,即使f()可能不直接接触任何ABC的类型,但实例化之间的Bar可能不同这一事实可能导致需要完全不同的代码,并且显然会生成完全不同的代码。

编译器

将准确生成您最终使用的重载数 - 如果您的代码最终为(A,B,C) n组合调用f<A,B,C>,您将生成n重载。没有不必要的膨胀。但是,模板参数推断发生在确切类型上。例如,您可能只有一个函数

void foo(double x);

并让这两个语句都有效

foo(1);//int implicitly promoted to double
foo(1.0);

但是,如果您有

template <typename T>
foo(T x);

您最终会生成两个重载。

foo(1);//T is deduced to be int, leading to initialization of foo<int>
foo(1.0);//T is deduced to be double, leading to initialization of foo<double>