当前位置:网站首页>Matching between class template with default template argument and template parameter
Matching between class template with default template argument and template parameter
2022-04-23 06:38:00 【mightbxg】
First, explain this strange looking title .
“ Class template with default template parameters ” Refer to Class template with default template-parameter, That is, some or all template parameters of a class template have default values , such as :
template<typename T1, typename T2 = int>
struct Foo {
};
A typical example is std::vector
, It actually has two template parameters :
template<class T, class Allocator = std::allocator<T>>
class vector;
But in most cases , We don't need to specify the second template parameter , It feels like it has only one template parameter , such as :std::vector<int> vec;
.
“ Template parameters ” namely Template template parameter, That is, template parameters with templates , such as :
template <template <typename> class C, typename T>
void bar(const C<T>& c) {
}
Inside C
Is a template parameter .
Now? , The problem is coming. , In the existing class Foo
And the function bar()
As defined , Can the following code be compiled ?
bar(Foo<int>{
});
This question is actually asking ,template<typename T1, typename T2 = int>
Can you talk to template <typename> class C
Match .
One side ,C
This class template can only have one template parameter , and Foo
There are two template parameters , So it seems that the two should not match . But on the other hand ,Foo
The second template parameter has a default value , In practical use, it can be regarded as having only one template parameter , So it seems to match C
.
The answer to this question is : Depends on the compiler !
See cppreference,C++17 A new feature has been introduced Matching template template parameters to compatible arguments ( Template parameters match compatible arguments , There seems to be no simpler name , Call it MTTP2CA Well ) To solve CWG 150 problem , Enables the following code to compile :
template<class T> class A {
/* ... */ };
template<class T, class U = T> class B {
/* ... */ };
template <class ...Types> class C {
/* ... */ };
template<template<class> class P> class X {
/* ... */ };
X<A> xa; // OK
X<B> xb; // OK in C++17 after CWG 150
// Error earlier: not an exact match
X<C> xc; // OK in C++17 after CWG 150
// Error earlier: not an exact match
therefore , I won't support it C++17 Your compiler cannot compile bar(Foo<int>{});
Of . But the problem is not limited to this , Even the latest Clang 12 and MSVC v19, Not even , Only GCC Be able to compile such code , Why is that ?
as a result of MTTP2CA The feature actually has a flaw , Suppose that bar()
Function adds a new definition :
template <template <typename, typename> class C, typename T1, typename T2>
void bar(const C<T1, T2>& c) {
}
here bar(Foo<int>{});
The match is void bar(const C<T>& c);
still void bar(const C<T1, T2>& c);
Well ?
Allied , If you add a new class template :
template <class>
struct Bar;
template <template <class> class X, class T>
struct Bar<X<T>> {
};
template <template <class, class> class X, class T, class U>
struct Bar<X<T, U>> {
};
that Bar<Foo<int>> a;
The match is Bar<X<T>>
still Bar<X<T, U>>
Well ?
In fact, these two situations are MTTP2CA There is no definition in , in other words C++ The standard does not specify that the former should be matched at this time ( A template parameter ) Or the latter ( Two template parameters ). My test results are GCC Will choose to match the latter .
Because this undefined situation ,Clang and MSVC This feature is hidden by default .Clang Can pass -frelaxed-template-template-args
Compile options to turn on the feature ,MSVC I haven't found a way to open it yet .
GCC and Clang The inconsistency on this issue also brings a more magical phenomenon : If you IDE It's using QtCreator, And turned on ClangCodeModel plug-in unit ( Automatically analyze code problems , Higher version QtCreator Default on ), So when compiling the previously mentioned code ,QtCreator Will report a mistake (ClangCodeModel be based on Clang Analyze the code ), But at the same time, it can compile successfully (Linux Upper QtCreator By default GCC As a compiler ).
版权声明
本文为[mightbxg]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204230546583477.html
边栏推荐
猜你喜欢
Robocode教程4——Robocode的游戏物理
Call procedure of function
【UDS统一诊断服务】四、诊断典型服务(2)— 数据传输功能单元
【UDS统一诊断服务】一、诊断概述(2)— 主要诊断协议(K线和CAN)
For() loop parameter call order
SQL sorts according to the specified content
【UDS统一诊断服务】(补充)五、ECU bootloader开发要点详解 (1)
Explanation of the second I interval of 2020 Niuke summer multi school training camp
7-21日错题涉及知识点。
Robocode教程5——Enemy类
随机推荐
OpenCV使用 GenericIndex 进行 KNN 搜索
【UDS统一诊断服务】四、诊断典型服务(5)— 功能/元件测试功能单元(例行程序功能单元0x31)
【UDS统一诊断服务】四、诊断典型服务(1)— 诊断和通信管理功能单元
Robocode教程4——Robocode的游戏物理
Flask - 中间件
【UDS统一诊断服务】四、诊断典型服务(3)— 读故障信息功能单元(存储数据传输功能单元)
C语言数组处理批量数据
【UDS统一诊断服务】(补充)五、ECU bootloader开发要点详解 (1)
实现一个计算m~n(m<n)之间所有整数的和的简单函数
带默认模板实参的类模板与模板模板形参的匹配
pyppeteer爬虫
Flask操作多个数据库
搭建openstack平台
产生随机数
拷贝构造函数
Make your own small program
[ThreadX] ThreadX source code reading plan (I)
1006 finding a mex (hdu6756)
Figure guessing game
【UDS统一诊断服务】(补充)五、ECU bootloader开发要点详解 (2)