考虑以下非法C ++ 11代码背后的意图:
struct Base
{
template<typename U>
virtual U convert() = 0;
};
template<typename T>
struct Derived : Base
{
T t;
template<typename U>
virtual U convert() { return U(t); }
};
struct Any
{
Base* b;
template<typename U>
operator U() { return b->convert<U>(); }
};
int main()
{
Any a = ...;
string s = a; // s = a->b->t if T is convertible to string
// fails otherwise with compile error or runtime exception
// (either acceptable)
}
有没有办法与合法代码达到相同或相似的效果?
(以上方式是非法的,因为templates may not be ‘virtual’
)
更新
struct Base
{
void* p;
type_info type;
};
template<typename T>
struct Derived : Base
{
Derived()
{
p = &t; // immovable
type = typeid(T);
}
T t;
};
struct Any
{
Base* b;
template<typename T = U, typename U>
operator U()
{
if (b->type != typeid(T))
throw exception();
T* t = (T*) b->p;
return U(*t);
}
};
答案 0 :(得分:0)
这是你想要的吗?
struct Base
{
virtual void* convert(const std::type_info&) = 0;
};
template<typename T>
struct Derived : Base
{
virtual void* convert(const std::type_info& ti)
{ return typeid(T) == ti ? &t : nullptr; }
T t;
};
struct Any
{
Base* b;
template<typename U>
operator U()
{
if (auto p = b->convert(typeid(U)))
return *static_cast<U*>(p);
throw std::exception();
}
};
正如另一个答案所说,很难确切地知道你想要什么,因为你只显示了无效的代码,没有解释你想要实现的目标。
编辑哦,我现在看到你希望它适用于任何可转换类型,而不仅仅是完全匹配......那么不,你不能将type_info
转回类型它表示,派生类型需要测试给定的type_info
是否对应于其存储类型可转换为的类型。您需要知道正确的类型,并通过演绎明确或隐式地指定以某种方式。如果您想将其转换为其他类型,则可以单独执行此操作:
Any a{ new Derived<int>() };
try {
char c = a; // throws
}
catch (...)
{
}
int i = a; // OK
char c = (int)a; // OK
答案 1 :(得分:-1)
根据您的更新,我认为这就是您要做的事情。
#include <typeinfo>
#include <exception>
#include <string>
template <typename T>
struct Any{
T* t;
Any():t(NULL){}
Any(const T& _t){
t=new T(_t);
}
template<typename U>
operator U(){
if(typeid(T)!=typeid(U) || t==NULL)
throw std::exception();
return *t;
}
};
int main (){
Any<std::string> a(std::string("Nothing"));
std::string b=a;
return 0;
};
如果这没有帮助,请在文字中解释,而不是代码你要实现的目标。告诉我们为什么要使用这两个额外的类Base和Derived会很有用。