类模板部分专用化等效性
Class template partial specialization equivalence
两个不同的类模板部分专用化声明何时匹配?
在下面的代码中,有两个部分专用化声明:
S<constrain<T,has_accept_>, void>
S<constrain<T,has_visit_>, void>
constrain
是一个别名模板,等于T
但使用enable_if
技巧进行约束,第二个参数作为概念。
GCC 认为这两个部分专用化是不同的,但 Clang 和 MSVC 认为它们是等价的,因此拒绝代码:
#include <type_traits>
#include <utility>
using namespace std;
template<class T,class=void>
struct has_accept
:false_type{};
template<class T>
struct has_accept<T,void_t<decltype(declval<const T&>().accept())>>
:true_type{};
template<class T,class=void>
struct has_visit
:false_type{};
template<class T>
struct has_visit<T,void_t<decltype(declval<const T&>().visit())>>
:true_type{};
//pre c++17 clang/MSVC fix: default argument of template
// used as template template argument not implemented yet
template<class T> using has_accept_ = has_accept<T>;
template<class T> using has_visit_ = has_visit<T>;
template<class T,template<class> class TT,class=enable_if_t<TT<T>::value>>
using constrain = T;
template<class T,class=void>
struct S
:false_type{};
template<class T>
struct S<constrain<T,has_accept_>,void> // (1)
:true_type{};
template<class T>
struct S<constrain<T,has_visit_>,void> // (2)
:true_type{}; // ==> MSVC and Clang: error (2) redefines (1)
我在标准中找不到任何可以指定部分专业化等效性的内容。[temp.type] 似乎不适用于这里。
该标准对部分专业化声明等效性有何规定?
这是CWG 1980,"等效但不是功能等效的重声明":
在类似的例子中
template<typename T, typename U> using X = T; template<typename T> X<void, typename T::type> f(); template<typename T> X<void, typename T::other> f();
看来,第二次
f
声明是对第一个声明的重新声明,但可以通过SFINAE区分,即等同但不在功能上等同。2014年11月会议记录:
CWG认为,这两个声明不应等同。
这仍然是一个活跃的问题。 GCC的行为更符合这些不同的愿望。[temp.alias]/2 和 [temp.alias]/3 是相关的透明度规则:
当模板 id 引用别名模板的专用化时,它等效于通过将其模板参数替换为别名模板的类型id中的模板参数而获得的关联类型。
但是,如果模板ID 是依赖的,则后续模板参数替换仍适用于模板 ID。
在这里有冲突。在问题的简化示例中,X<T, U>
等效于T
- 这意味着两个声明都只有返回类型的void
- 但替换仍然适用,这并不完全意味着它们是等效的。
相关文章:
- .cpp和.h文件中的模板专用化声明
- 调用专用模板时出错"no matching function for call to [...]"
- 模板专用化(按容器):value_type
- 如何用RISC-V GD32VF103CBT6开发板卸载精确的ADC过采样
- 如何将部分流作为参数传递
- 静态数据成员模板专用化的实例化点在哪里
- 特征 3 类的模板专用化
- Visual Studio 2017 不允许我创建 C++ 专用模板
- 我是 c++ 的新手.学习基本知识后,我想做井字游戏.对于印刷板,我在下面写代码,但它显示错误
- 字符串化递归的"std::vector<std::vector<...>>"而不使用部分模板函数专用化
- 具有常量引用参数的函数模板专用化
- 使用其他模板的模板专用化
- 使用专用显卡进行 OpenGL 渲染时帧速率较低
- 使用类型特征的部分类专用化
- 将 CRTP 与部分类专用化结合使用?
- 针对多种类型的部分类模板专用化
- 参数包不在最后位置的部分类模板专用化
- 具有多个参数的部分类模板专用化
- 函数指针类型和值的部分类专用化
- 带有映射的部分类模板专用化