0

如何优雅 Wrapper地限制模板参数?Wrapper<Any,MyArray<AnyT>>

  1. 不要破坏内容辅助 (Visual Studio)。
  2. 高可读性。不要使用 hacky 方法。
    由于某些原因,大多数解决方案都喜欢破解。
  3. 使用 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) 来强制执行T2is 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。
不幸的是,内容辅助讨厌它。

参考

这是我阅读的其他链接:-

4

1 回答 1

1

您可以编写自定义类型 trait is_specialization,如下所示:

template<class Type, template<class...> class Template>
struct is_specialization
  : std::false_type {};
template<template<class...> class Template, class... TArgs>
struct is_specialization<Template<TArgs...>, Template>
  : std::true_type {};

然后你只需要对给static_assertis_specialization的模板参数是真的:

template<class T,class T2>
class Wrapper {
    static_assert(is_specialization<T2, MyArray>::value, "T2 must be a specialization of MyArray");
};
于 2017-04-26T08:29:00.200 回答