【问题标题】:Do c++ concepts cause template instantiations to be written to build output?c++ 概念是否会导致编写模板实例化来构建输出?
【发布时间】:2021-01-27 21:39:37
【问题描述】:

对于具有许多大型和复杂模板实例化的库,在我看来,决定是否使用概念的主要考虑因素之一是构建输出的大小是否更小。

对于 SFINAE,我的理解是以下代码将导致模板实例化 std::is_function<bar>std::enable_if<true, bool> 包含在构建输出中,从而增加其大小(尽管在本示例中略有增加):

#include <type_traits>

template<typename F,
         typename = std::enable_if_t<
                    std::is_function<F>::value,
         bool> = true>
void foo(F& f)
{
    // do some stuff with f
}

void g();

int main()
{
    foo(g);
    return 0;
}

如果改用基于std::is_function 的C++20 概念,显然必须实例化模板才能对其进行检查。但是那个实例化然后被写入最终的构建输出吗?这是否因编译器实现而异?

#include <type_traits>

template<typename F>
concept Function = std::is_function<F>::value;

template<Function F>
void foo(F& f)
{
    // do some stuff with f
}
//...

【问题讨论】:

  • 您似乎可以在您关心的平台上轻松编译此代码并很快找到答案。你有理由不能这样做吗?我不认为这可能是语言律师的问题或为所有编译器提供答案,因为这似乎是实现质量问题,而不是标准问题。

标签: c++ templates c++20 c++-concepts


【解决方案1】:

您似乎担心代码大小。

类,在这里我包括类模板的实例化,只是编译器知道的抽象信息片段。它们不会影响代码大小。

只有函数(包括成员函数)会影响代码大小。类模板的成员函数仅在它们被实例化时才会影响代码大小,因为它们的使用方式需要它(C++ 标准称之为“ODR-used”)。

在您的示例中,std::is_functionstd::enable_if 的任何成员函数都没有被 ODR 使用,因此它们没有被实例化,并且它们不影响代码大小。

但是那个实例化然后会写入最终的构建输出吗?

没有生成代码。但通常编译器会将调试信息写入输出。从这个意义上说,有些东西 被写入了输出。

这是否因编译器实现而异?

就调试信息而言:是的。但是是否发生实例化是由语言的规则决定的,编译器之间应该没有区别。

【讨论】:

  • 嗯,我一直不太明白“ODR-used”是什么意思。纯粹的抽象基础和“混入”的想法以一种全新的方式吸引了我。当您说只有函数会影响代码大小时,这是否也适用于非模板类?如果是这样的话,我认为我肯定需要进一步深入了解,如果只是为了好奇的话。
  • @mousebyte 是的,非模板类也是如此。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多