如何优雅 Wrapper
地限制模板参数?Wrapper<Any,
MyArray
<AnyT>>
- 不要破坏内容辅助 (Visual Studio)。
- 高可读性。不要使用 hacky 方法。
由于某些原因,大多数解决方案都喜欢破解。 - 使用 C++ 语法规则在第一行使其显而易见。(不仅仅是绿色评论)
据我所知,有很多解决方案,但每个解决方案都不符合标准。
解决方法 1(模板专业化,失败 1)
template<class T> class MyArray{};
template<class T,class T2> class Wrapper;
template<class T,class T2> class Wrapper<T,MyArray<T2>>{
using Test=int;
};
class B{};
class C{};
int main() {
Wrapper<C,MyArray<B>> wrapper;
return 0;
}
此代码是从https://stackoverflow.com/a/43518221 (@max66) 修改的。
IDE 的上下文线索/语法高亮会混淆。
就我而言,它将一些正确的类型标记为错误,例如:-
class ShowError : public Wrapper<B,MyArray<C>>{
Test n=0; //<-- unknown "Test" (intellisense)
};
解决方法 2(一些 hacky 字段/typedef,失败 2)
template<class T> class MyArray{
public: using MyArrayT=T;
};
template<class T,class T2> class Wrapper{
public: using myT=typename T2::MyArrayT;
//^ assert at compile time
};
这个想法来自https://stackoverflow.com/a/43518295 (@Jarod42)中的评论
类声明没有提到MyArray
,它只是使用一种 hacky(可读性较差)方式 ( MyArrayT
) 来强制执行T2
is MyArray
。
解决方法 3(基类,失败 2)
class MyArrayBase{};
template<class T> class MyArray : public MyArrayBase{ };
template<class T,class T2> class Wrapper{
//check something around MyArrayBase *object = new T2();
// or "is_base_of"
};
代码从Restrict C++ Template Parameter 修改为 Subclass和仅接受某些类型的 C++ 模板。
它与解决方法2具有相同的缺点。
对于普通用户来说并不明显。
解决方法 4(SNIFAE,失败 1)
通过添加std::enable_if
模板类声明 ( Wrapper
),我可以获得有效的 hack。
不幸的是,内容辅助讨厌它。
参考
这是我阅读的其他链接:-
- http://www.informit.com/articles/article.aspx?p=376878(模板模板参数)
- 限制模板函数,只允许某些类型(与模板类型无关作为参数)