根据https://gcc.gnu.org/projects/cxx-status.html,使用标志
我期望以下代码能够编译通过,特别是因为
1. 编译器知道无法创建
2. 指向基类
-std=c++1z
的g++ 7版本支持类模板的模板参数推导。我期望以下代码能够编译通过,特别是因为
Base
是一个抽象类,因此:1. 编译器知道无法创建
Base
的任何实例;2. 指向基类
pt_base
的指针指向一个明确定义的实例(即Derived<int>{42}
),其中类型(int
)是显式的。template<typename ValueType>
class Base {
public:
virtual ValueType getValue() = 0;
};
template<typename ValueType>
class Derived : public Base<ValueType>{
public:
Derived(ValueType argt){ value = argt; }
virtual ValueType getValue(){ return value; }
ValueType value;
};
int main(){
Base *pt_base = new(Derived<int>{42}); // *ERROR*
delete pt_base;
}
然而,它无法编译。G++抱怨说“模板占位符类型'Base'必须跟随一个简单的声明符标识符”;如果我理解正确,它没有推导出模板参数。
很遗憾,因为我想动态决定pt_base
指向哪个派生类(可以是来自类Derived<someType>
或类Derived2<someType2>
的对象)。这样,一个数组或vector<Base *>
可以存储指向各种派生类对象的指针。
GCC目前只实验性地支持C++17,而且我没有其他编译器的访问权限,所以尽管我得到了编译错误,但我不确定我的代码是否有错。你认为呢?
我们如何动态决定pt_base
指向Derived<someType>
或Derived2<someType2>
中的一个对象(以便可以使用多态性)?
Base *pt_base
中的*
不被允许。*pt_base
是一个声明符,但不是一个声明符标识符(比如未装饰的标识符)。我在 N4687 中找不到这个规则。 - ascheplerBase
的情况下,编译器将决定它实际上是否意味着Base<someType>
或其他内容。Base
不是一种类型。因此,除非它们实际上都继承了某个公共类型,否则您无法使单个变量在运行时指向Derived<someType>
或Derived<someType2>
。您可能需要使用std::any
或std::variant
作为其getValue()
的返回类型。 - ascheplervector<Base*>
是有效的,类型擦除将直接由语言支持... - Walter