c++ - 模板模板函数的重载 - 显式调用

标签 c++ templates template-templates

因此,首先考虑以下从函数参数中隐式知道模板参数的情况:

#include <iostream>
using namespace std;

class A {};
class B {};

template <class T1, class T2>
class C { 
    T1 a; 
    T2 b; 
};

template <class T1>
class D {
    T1 a;
};

template <template<class, class> class TC, class TA, class TB>
void foo(TC<TA, TB> c) {
    std::cout << "T<T,T>" << std::endl;
};

template <template<class> class TD, class TA>
void foo(TD<TA> d){
    std::cout << "T<T>" << std::endl;
};

int main() {
    C<A,B> c;
    D<A> d;

    foo(c);
    foo(d);
}

输出如你所料:

T<T,T>
T<T>

但是,如果我没有 C 类的实例怎么办?和 D所以我需要明确调用正确的重载?这将如何完成?即,有一个 main()包括:

int main() {
    foo<C<A,B> >();
    foo<D<A> >();
}

我已经尝试了一些 foo() 的重载如下图:

template <template<class, class> class TC>
void foo() {
    std::cout << "T<T,T>" << std::endl;
};

template <template<class> class TD>
void foo(){
    std::cout << "T<T>" << std::endl;
};

template <template<class, class> class TC, class TA, class TB>
void foo() {
    std::cout << "T<T,T>" << std::endl;
};

template <template<class> class TD, class TA>
void foo(){
    std::cout << "T<T>" << std::endl;
};

但是,这(以及我能想到的所有排列)只会导致如下所示(缩写)输出的一系列错误

prog.cpp: In function 'int main()':
prog.cpp:44:18: error: no matching function for call to 'foo()'
     foo<C<A,B> >();
                  ^
prog.cpp:44:18: note: candidates are:
prog.cpp:19:6: note: template<template<class, class> class TC> void foo()
 void foo() {
      ^
prog.cpp:19:6: note:   template argument deduction/substitution failed:
prog.cpp:24:6: note: template<template<class> class TD> void foo()
 void foo(){
      ^
prog.cpp:24:6: note:   template argument deduction/substitution failed:

我想做的事情是否允许?如果是这样,我哪里搞砸了?

----编辑----

正如 apple apple 指出的那样,如果我的 main()如下:

int main() {
    foo<C, A, B>();
    foo<D, A>();
}

我得到了预期的输出。

但是,我的真实案例最终变得更加复杂。我会在这里展开一点。遗留代码在其他地方的 header 中定义了(数百个)typedef:

typedef C<A, B> type_117;
typedef D<A>    type_252;

我正在处理的类是模板化的,并使用其中一个 typedef 作为模板参数进行实例化。所以一些事情是这样的:

template <class Type>
class Test
{
public:
   Test();
   SomeClass mSC;
}
Test::Test()
  : mSC(foo<Type>())
{
};

其中 Test 被实例化为

Test<type_117> aTest;

所以我一直在想怎么写foo()对于这种情况。在这一点上,我调用 foo()在我的Test的初始值设定项我是否能够“分解”它以生成 <C,A,B>形式?还是我遇到了障碍,需要重新设计一些现有框架?

最佳答案

template<class T>struct tag_t{constexpr tag_t(){}};
template<class T>constexpr tag_t<T> tag{};

这些是类型标签。它们可以在没有类型实例的情况下传递给函数。

模板函数将推导它们。

template <template<class, class> class TC, class TA, class TB>
void foo(tag_t<TC<TA, TB>>) {
  std::cout << "T<T,T>" << std::endl;
};

template <template<class> class TD, class TA>
void foo(tag_t<TD<TA>>){
  std::cout << "T<T>" << std::endl;
};

在调用站点执行 foo(tag<type_117>)正如他们所说,鲍勃是你的叔叔。

在 C++98 中(恶心):

template<class T>struct tag_t{};
foo(tag_t<type_117>());

关于c++ - 模板模板函数的重载 - 显式调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43124468/

相关文章:

c++ - 使用filestream实现高分

C++ 连接许多 std::vectors 并删除重复项

templates - 样式表不适用于使用 chi 路由器的 go html 模板

css - WooCommerce 页面 CSS 文件

c++ - 为什么只有定义了类才能将数据成员指定为类类型? (来自书 "C++ primer")

c++ - 基于std::array的多维数组初始化

c++ - 如何在 C++ 中模拟模板化的 std::function

c++ - 模板模板条件编译

c++ - 扩展模板<class>类的参数包

c++ - 如果没有提供 Container::value_type,如何获取 C++ Container<T> 的 T?