以下是我的情况:
template <typename T>
struct Foo
{
Foo() {}
Foo(T data) : _data(data) {}
T _data;
};
struct Holder
{
Holder() {}
Holder(int a) : foo(a) {}
virtual Foo<int> getFoo() { return foo; }
virtual std::string type() { return "holder"; } // EDIT 2 EDIT 3: added virtual
Foo<int> foo;
};
struct HolderInt : public Holder
{
HolderInt() {}
HolderInt(int a) : Holder(a) {}
std::string type() { return "holderint"; } // EDIT 2
};
struct HolderString : public Holder
{
HolderString() {}
HolderString(std::string a) : Holder(0), foo(a) {}
Foo<std::string> getFoo() { return foo; } // here is the dilema
std::string type() { return "holderstring"; } // EDIT 2
Foo<std::string> foo;
};
int main()
{
std::vector<Holder*> holders;
holders.push_back(new HolderString());
return 0;
}
我正在寻找一种方法来实现这一目标。我希望让这个工作的方式是保持一个吸气剂,但如果我错过了一些对我的情况非常有用的东西,那将是很好的。
编辑:我知道虚函数不能有不同的返回类型,但我正在寻找另一种选择。很抱歉没有这么说。编辑2:在进一步审查我的代码后,我意识到我错过了一些重要的东西。我有一个&#34;到字符串&#34;函数可以这么说,我将编辑。这可以帮助我区分每种结构类型,即使它们具有相同的foo。在我看了一段时间之前,我不知道自己没有看到这个,但是我能够使用虚拟功能解决这个问题。
答案 0 :(得分:0)
如果我理解你的问题,请尝试以下方法:
template <typename T>
struct foo
{
T data;
foo() {}
foo(T d) : data(d) {}
void set(T d) { data = d; } // Good practice to also have a setter
T get() { return data; }
};
struct holder_int
: public foo<int>
{
holder_int(int i) : foo(i) {}
};
struct holder_str
: public foo<std::string>
{
holder_str(const std::string& str) : foo(str) {}
};
这使用单个通用(模板)结构foo
,它还具有通用(模板)get函数。从该结构继承的每个结构都在foo中设置类型(如果这是有意义的)。基本上,包含整数的结构将继承自foo<int>
,而包含double的结构将从foo<double>
继承。
答案 1 :(得分:0)
这不起作用。在编译时,编译器必须具有每个变量的类型。让我们假装你可以做你想做的事情
// illegal code
struct Holder {
virtual ? get() = 0;
};
struct HolderInt : Holder {
int get() override { return 0; }
};
struct HolderString : Holder{
std::string get() override { return ""; }
};
现在假设你有一个Holder*
void func(Holder* holder) {
auto t = holder->get(); // type of t must be known at compile-time
constexpr auto sz = sizeof t; // must be known at compile-time
using Type = decltype(t); // must be known at compile-time
}
编译时必须知道t
的类型,但是您的代码在运行时才会知道这一点。