对于具有许多大型和复杂模板实例化的库,在我看来,决定是否使用概念的主要考虑因素之一是构建输出的大小是否更小。
使用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++标准将其称为"odr -used")。
在您的示例中,std::is_function
和std::enable_if
的成员函数都没有使用odr,因此它们没有被实例化,并且它们不影响代码大小。
但是,实例化然后写入最终构建输出吗?
不生成代码。但编译器通常会将调试信息写入输出。在这种意义上,一些被写入输出。
这取决于编译器的实现吗?
就调试信息而言:是。但是是否发生实例化是由语言规则控制的,编译器之间不应该有区别。