C++ 概念是否会导致编写模板实例来构建输出?
Do c++ concepts cause template instantiations to be written to build output?
对于具有许多大型复杂模板实例化的库,在我看来,决定是否使用概念的主要考虑因素之一是构建输出的大小是否较小。
对于 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
}
//...
看来您担心代码大小。
类,这里我包括 class 模板的实例化,只是编译器知道的抽象信息。它们不会增加代码大小。
只有函数(包括成员函数)会影响代码大小。 class 模板的成员函数仅在实例化时才影响代码大小,因为它们的使用方式需要它(C++ 标准称之为“ODR-used”)。
在您的示例中,std::is_function
和 std::enable_if
的成员函数均未使用 ODR,因此它们未被实例化,并且不会增加代码大小。
But is that instantiation then written to the final build output?
没有生成代码。但通常编译器会将调试信息写入输出。从这个意义上说, 是 写入输出。
And does this differ depending on compiler implementation?
就调试信息而言:是的。但是是否实例化是由语言规则决定的,编译器之间应该没有区别。
对于具有许多大型复杂模板实例化的库,在我看来,决定是否使用概念的主要考虑因素之一是构建输出的大小是否较小。
对于 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
}
//...
看来您担心代码大小。
类,这里我包括 class 模板的实例化,只是编译器知道的抽象信息。它们不会增加代码大小。
只有函数(包括成员函数)会影响代码大小。 class 模板的成员函数仅在实例化时才影响代码大小,因为它们的使用方式需要它(C++ 标准称之为“ODR-used”)。
在您的示例中,std::is_function
和 std::enable_if
的成员函数均未使用 ODR,因此它们未被实例化,并且不会增加代码大小。
But is that instantiation then written to the final build output?
没有生成代码。但通常编译器会将调试信息写入输出。从这个意义上说, 是 写入输出。
And does this differ depending on compiler implementation?
就调试信息而言:是的。但是是否实例化是由语言规则决定的,编译器之间应该没有区别。