C++ 如何使用两个模板参数指定共享模板变量?
我正在尝试构建一个小型测试框架。我有一个函数,它接受由相同类型组成的两个类似列表的变量,我计划将模板参数用作接口的一部分。到目前为止,我有这个C++ 如何使用两个模板参数指定共享模板变量?,c++,templates,template-templates,C++,Templates,Template Templates,我正在尝试构建一个小型测试框架。我有一个函数,它接受由相同类型组成的两个类似列表的变量,我计划将模板参数用作接口的一部分。到目前为止,我有这个 template <typename C, template <class> class A, template <class> class B> static inline void assertEquals(const A<C>& expected, const B<C&g
template <typename C, template <class> class A, template <class> class B>
static inline void assertEquals(const A<C>& expected, const B<C>& actual) {
auto success = 0, failure = 0;
for (auto iter1 = expected.cbegin(), iter2 = actual.cbegin();
iter1 != expected.cend() && iter2 != actual.cend(); ++iter1, ++iter2) {
if (Test::assertEquals<C>(*iter1, *iter2)) {
++success;
} else {
++failure;
}
}
cout << "Success: " << success << endl
<< "Failure: " << failure << endl;
}
Test::
只是函数所在的类,而haystack
和needle
的类型是std::vector
,您的接口不会接受std::vector
,因为它实际上需要两个模板参数:包含的类型和一个分配器
您可以更改模板签名以接受可变模板模板,如下所示:
template <typename C, template <class...> class A, template <class...> class B>
static inline void assertEquals(const A<C>& expected, const B<C>& actual) {
template <class A, class B>
void assertEquals(const A& expected, const B& actual) {
static_assert(std::is_same<typename A::value_type, typename B::value_type>::value,
"Containers must have the same value type");
using C = typename A::value_type;
//...
这是一个更简单的界面。对于以上所有选项,编译器都可以为您推断模板参数,因此只需按如下方式调用:
assertEquals(haystack, needle);
std::vector
实际上是std::vector
。您真的需要在Test::assertEquals
中提供C
?它能从论点中推断出来吗?(如果是,assertEquals(常数T1和预期值,常数T2和实际值)
就足够了)。@Jarod42正确。这是否意味着我无法将其初始化为std::vector
?我想既然Alloc
是T
的函数,我可以简单地包括T
。这似乎是我做错的一个关键问题,正如@TartanLlama也指出的,你可以说std::vector
,因为std::vector
定义了一个默认值用作第二个模板参数。我想这也行得通。如果我想使用模板参数路径,这是否意味着C
现在是一个pack变量,并且在函数参数中使用它将如下所示,。。。常量A和预期值,
?不,C
仍然是一个类。使模板模板可变实际上是告诉编译器接受任何模板模板,这样您就可以让默认参数生效,而不必显式声明它。那么这个接口的实例化是什么样子的呢?您可以用运行时参数调用它,让编译器推导出类型,看我的编辑。我忘了模板可以这样推断。这比我的眼睛还难看。谢谢
template <class A, class B>
void assertEquals(const A& expected, const B& actual) {
static_assert(std::is_same<typename A::value_type, typename B::value_type>::value,
"Containers must have the same value type");
using C = typename A::value_type;
//...
assertEquals(haystack, needle);