从模板化类虚拟函数中调用的模板函数不正确
Incorrect template function being called from within a templated class virtual function
我正在尝试从类的被覆盖的虚拟函数中调用模板化函数。 不幸的是,我似乎只能调用默认实现。
#include <iostream>
#include <string>
#include <typeinfo>
#include <memory>
template<typename T1,
typename T2>
class B;
template<typename T1,
typename T2>
void bar(B<T1, T2> &b)
{
std::cout << "T1 = " << typeid(T1).name() << std::endl;
std::cout << "T2 = " << typeid(T2).name() << std::endl;
std::cout << "Default template" << std::endl;
}
template<typename T2>
void bar(B<int, T2> &b)
{
std::cout << "Specialized template" << std::endl;
}
template<typename T1, typename T2>
void foobar(T1 t1, T2 t2)
{
std::cout << "Default template [foobar]" << std::endl;
}
template<typename T2>
void foobar(int t1, T2 t2)
{
std::cout << "Specialized template [foobar]" << std::endl;
}
class A
{
public:
A() {}
~A() {}
virtual void foo() = 0;
};
template<typename T1,
typename T2>
class B : public A
{
public:
B() {}
~B() {}
void foo() override
{
std::cout << "T1 = " << typeid(T1).name() << std::endl;
std::cout << "T2 = " << typeid(T2).name() << std::endl;
bar<T1, T2>(*this);
}
};
int main()
{
auto a = new B<int, char>();
a->foo();
bar<int, char>(*a);
int i = 0;
char b = 'b';
foobar(i, b);
foobar(b, b);
return 0;
}
输出是(见:这里(
T1 = i
T2 = c
T1 = i
T2 = c
Default template
T1 = i
T2 = c
Default template
Specialized template [foobar]
Default template [foobar]
显然,被覆盖的 foobar 函数工作正常,但是,对于bar
函数,从未调用专用版本。控制台中的输出显示第一个模板参数显然是一个 int,因此应调用被覆盖的 bar 函数。
我有一种感觉,这与虚拟函数foo
与类模板 [1] 不兼容有关。原则上,我想生成不同版本的B
类,这些版本将覆盖虚拟foo
函数并调用 bar 的适当专业化(取决于类模板参数(。
我知道我可以只拥有 B 类的部分专业化,但这会导致我的设计出现大量重复代码和其他复杂性。(我也知道其中一些可以通过模板化继承来缓解(。
我主要只是好奇为什么尽管模板参数显然是正确的,但没有调用正确的bar
版本。我不仅想知道为什么会有冲突,而不仅仅是完全重新设计的建议。
这里的问题是bar
实际上是两个独立的模板函数重载,第一个具有优先级。要为函数模板定义部分专用化,您可以使用代理模板类来完成所有工作的技巧:
template<typename T1, typename T2> class
bar_impl
{
public: static void
Do(B<T1, T2> &b)
{
std::cout << "T1 = " << typeid(T1).name() << std::endl;
std::cout << "T2 = " << typeid(T2).name() << std::endl;
std::cout << "Default template" << std::endl;
}
};
template<typename T2> class
bar_impl<int, T2>
{
public: static void
Do(B<int, T2> &b)
{
std::cout << "Specialized template" << std::endl;
}
};
template<typename T1, typename T2> void
bar(B<T1, T2> &b)
{
return bar_impl<T1, T2>::Do(b);
}
在线编译器
相关文章:
- 函数调用中参数的顺序重要吗
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 变量没有改变?通过向量的函数调用
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 我知道函数调用中存在歧义.有没有办法调用foo()函数
- 模板函数调用
- 获取从C++中同一类中的构造函数调用的方法返回的值
- 析构函数调用
- 成员函数调用和C++对象模型
- 使用共享指针的函数调用,其对象应为 const
- C++:编译时检查匹配的函数调用对?
- 函数调用C++中的参数太少
- 来自 DLL 的函数调用 [表观调用的括号前面的表达式必须具有(指向-)函数类型]
- 返回指向对象的指针的函数调用是否为 prvalue?
- C++ 如何重载 [] 运算符并进行函数调用
- 代码的效率. 转到和函数调用
- 是同一作用域的函数部分中的函数调用
- 如何封装一个函数,以便它只能由同一类中的一个其他函数调用?
- 类型擦除的std::function与虚拟函数调用的开销