我想为名称未知的类进行模板特化,我只知道它们的基础,并且我希望所有派生类都落在专门的模板函数上。
以下代码适用于案例1-4。我无法使案例5起作用。 这也主要是使用is_base_of进行运行时检查,更有效的是编译时解决方案,但我失败了。 :(
#include <typeinfo>
#include <iostream>
struct MyClass {};
struct Rnd : public MyClass {};
void* JustAVoidPointer=new int;
void* AnOtherPointer = new int;
struct A
{
template <typename T> operator T() const {
if (std::is_base_of<MyClass, T>::value == true)
{
JustAVoidPointer = (MyClass*)(new T);
std::cout << "Case 3"; return *((T*)(JustAVoidPointer));
}
std::cout << "Case 1"; return *((T*)AnOtherPointer);
}
//template <typename T> operator T&() {
// std::cout << "Case 5"; return *(this->operator T* ());
//}
template <typename T> operator T*() const {
if (std::is_base_of<MyClass, T>::value == true)
{
JustAVoidPointer = (MyClass*) new T;
std::cout << "Case 4"; return (T*)(JustAVoidPointer);
}
std::cout << "Case 2"; return *((T**)AnOtherPointer);
}
}a;
void main()
{
auto CantUseTheStructsName = [&]() {
struct Rnd : public MyClass {};
int z = a; //Case 1
int* w = a; //Case 2
Rnd x = a; //Case 3
Rnd* y = a; //Case 4
//Rnd& z=a; //Case 5
char* xx=0; std::cin >> xx;
}; CantUseTheStructsName();
}
感谢您给我的任何帮助或建议,谢谢!:)
答案 0 :(得分:0)
我感觉不可能区分参考操作员模板和非参考操作员模板,如果我们提供两者,参考操作员模板总是优先考虑。 解决方法和编译时解决方案:
#include <typeinfo>
#include <iostream>
struct MyClass {};
struct Rnd : public MyClass {};
void* JustAVoidPointer=0;
void* AnOtherPointer = new int;
struct A
{
template <typename T, typename F = T*> operator T&() const {
return *((T*)CheckType(F{}, std::is_pointer<T>{}, std::is_base_of<MyClass, std::remove_pointer<T>::type>{}));
}
template <typename T> T* CheckType(T*, std::false_type, std::false_type) const {
std::cout << " Case 1";
return ((T*)AnOtherPointer);
}
template <typename T> T* CheckType(T*, std::true_type, std::false_type) const {
std::cout << " Case 2";
return ((T*)AnOtherPointer);
}
template <typename T> T* CheckType(T*, std::false_type, std::true_type) const {
std::cout << " Case 3";
JustAVoidPointer = (MyClass*)(new T);
return ((T*)JustAVoidPointer);
}
template <typename T> T* CheckType(T*, std::true_type, std::true_type) const {
std::cout << " Case 4";
JustAVoidPointer = (MyClass*)(new std::remove_pointer<T>::type);
return ((T*)(&JustAVoidPointer));
}
}a;
void main()
{
auto CantUseTheStructsName = [&]() {
struct Rnd : public MyClass {};
int x = a; //Case 1
int& y = a; //Case 1
int* z = a; //Case 2
Rnd j = a; //Case 3
Rnd& k = a; //Case 3
Rnd* f = a; //Case 4
char* xx=0; std::cin >> xx;
}; CantUseTheStructsName();
}