因此,首先考虑以下从函数参数中隐式知道模板参数的情况:
#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/