源码释义
namespace templateTemplateParameter
{
// 双重模板参数
#if !defined(__PRETTY_FUNCTION__) && !defined(__GNUC__)
# define __PRETTY_FUNCTION__ __FUNCSIG__
#endif
template <typename T, template <class, class...> class C, class... Args>
std::ostream& operator<<(std::ostream& os, const C<T, Args...>& objs)
{
// 可以将参数全部打印出来
os << "FUNC DETAIL: " << __PRETTY_FUNCTION__ << '\n';
for (auto const& obj : objs)
os << obj << ' ';
return os;
}
template <template <class> class H, class S>
S calcListTotalValue(const H<S>& ls)
{
auto a = std::begin(ls);
auto b = std::end(ls);
S totalValue{};
for (auto i = a; i != b; ++i)
{
totalValue += *i;
}
return totalValue;
}
//template <template <class, class> class V, class T, class A>
template <template <typename, typename> class V, typename T, typename A>
T calcListTotalValue2(V<T, A>& ls)
{
auto a = std::begin(ls);
auto b = std::end(ls);
T totalValue{};
for (auto i = a; i != b; ++i)
{
totalValue += *i;
}
return totalValue;
}
void testMain()
{
std::cout << "\ntemplateTemplateParameter::testMain() begin.\n";
std::list<int> list_01{10,3,5};
auto value1 = calcListTotalValue<std::list, int>(list_01);
value1 = calcListTotalValue<std::list>(list_01);
std::cout << "value1: " << value1 << "\n";
calcListTotalValue2<std::list, int>(list_01);
auto value2 = calcListTotalValue2(list_01);
std::cout << "value2: " << value2 << "\n";
std::cout << "list_01: " << list_01 << "\n";
std::cout << "templateTemplateParameter::testMain() end.\n";
}
} // namespace templateDefTest03
打印输出如下所示:
templateTemplateParameter::testMain() begin.
value1: 18
value2: 18
list_01: FUNC DETAIL: class std::basic_ostream<char,struct std::char_traits<char> > &__cdecl templateTemplateParameter::operator <<<int,class std::list,class std::allocator<int>>(class std::basic_ostream<char,struct std::char_traits<char> > &,const class std::list<int,class std::allocator<int> > &)
10 3 5
templateTemplateParameter::testMain() end.
通过上述宏信息输出,可以清楚的看到函数的具体形态。
MSVC中__FUNCSIG__宏
__FUNCSIG__
:定义为包含封闭函数签名的字符串文本。 此宏仅在函数中定义。 如果使用 /EP 或 /P 编译器选项,则不会展开 __FUNCSIG__
宏。 当针对 64 位目标进行编译时,调用约定默认为 __cdecl
。 有关用法的示例,请参阅 __FUNCDNAME__
宏。
细节请见: 预定义宏 | Microsoft Learn
关于__PRETTY_FUNCTION__宏
在linux系统中用g++编译C++程序, __FUNCTION__宏只输出类的成员函数名,不会输出类名。而__PRETTY_FUNCTION__宏则会以 <return-type> <class-name>::<member-function-name>(<parameters-list>) 的格式输出成员函数的详悉信息(注:只会输出parameters-list的形参类型,而不会输出形参名)。