使用 SFINAE、约束或概念限制专业化
limiting specializations using SFINAE, Constraints or Concepts?
以下程序运行良好:
struct M; // forward declare so compiler will recognize this type
struct N;
template< typename J > struct B { template< typename U > void Func1(); };
template<> template<> void B< M >::Func1< M >() {}
template<> template<> void B< N >::Func1< N >() {}
template<> template<> void B< M >::Func1< N >() {} // illegal specialization for this app
template< typename J > struct C { template< typename U > void Func2(); };
template<> template<> void C< M >::Func2< M >() {}
template<> template<> void C< N >::Func2< N >() {}
template< typename G > struct H { G g; };
int main()
{
H< B< M > > hbm;
hbm.g.Func1< M >(); // ok
hbm.g.Func1< N >(); // compiles and runs, but uses a semantically illegal specialization for this app
H< B< N > > hbn;
hbn.g.Func1< N >(); // ok
H< C< M > > hcm;
hcm.g.Func2< M >(); // ok
H< C< N > > hcn;
hcn.g.Func2< N >(); // ok
return 0;
}
重要的是,在编译时显式声明结构 B 和 C,并且只允许那些对应用有意义的专用化。
但正如上面的代码所示,我的下游开发人员(有一天!)可能会创建语法正确的模式,这些模式在语义上没有意义。具体来说,该应用程序只知道如何使用类和函数类型相等的类型。其余的都是无厘头的。
这似乎是新的 C++17+ 功能之一,如 SFINAE、约束或概念。虽然我正在阅读这些,但我还没有做出这个选择的判断力。在替代方案下的cpp首选项中,如果编译器有能力,他们建议使用概念而不是SFINAE(我使用VS2015)。
将类型名 J 限制为与类型名 U 相同的好方法是什么?
您可以使用
enable_if:
template< typename J > struct B {
template<typename U>
typename std::enable_if<std::is_same<U, J>::value, void>::type
Func1();
};
http://coliru.stacked-crooked.com/a/efb499cf654f0f25
对于概念(在不久的将来(?)不是标准),与上述相同的解决方案如下所示。
http://melpon.org/wandbox/permlink/li4Uh5Q6ilpnlhcl
template <class T, class U> concept bool Same = std::is_same<T,U>::value;
template< typename J > struct B {
template< typename U >
requires Same<J, U>
void Func1();
};
相关文章:
- 如何使用默认参数等选择模板专业化
- 模板化建造师专业化
- 为什么使用SFINAE而不是函数重载
- 类模板的成员功能的定义在单独的TU中完全专业化
- 如何使用模板函数的函数签名进行SFINAE
- 数据成员SFINAE的C++17测试:gcc vs clang
- 使用在用于SFINAE的void_t中具有参数的方法
- 编译器如何在使用SFINAE的函数和标准函数之间确定两者是否可行
- 提供与TMP和SFINAE的通用接口
- 部分专业化和嵌套模板
- 模板专业化可以进入我的.cpp吗?
- "Inverse SFINAE"避免模棱两可的过载
- 别名模板的专业化 C++11 中没有开销的最佳替代方案
- 是否可以混合使用SFINAE和模板专业化?
- 使用void_t的多个SFINAE类模板专业化
- 部分模板专业化 SFINAE
- 部分专业化和SFINAE
- variadic模板专业化,std :: enable_if,sfinae
- 使用 SFINAE、约束或概念限制专业化
- 禁用默认模板,仅通过sfinae使用专业化