C ++中类模板的模板参数推导17:我做错了吗? [英] Template argument deduction for class templates in C++17: am I doing it wrong?
问题描述
根据
https://gcc.gnu.org/projects /cxx-status.html ,与标记 -std = c ++ 1z
一起使用的g ++版本7支持类模板的模板参数推导。 p>
我期望编译下面的代码,特别是 Base
是一个抽象类,因此:
1.编译器知道可以创建 Base
的实例;
2.指向base pt_base
指向一个明确定义的实例(即 Derived
),其中类型( int $ c $
模板< typename ValueType>
class Base {
public:
virtual ValueType getValue()= 0;
};
模板< typename ValueType>
class Derived:public Base< ValueType> {
public:
Derived(ValueType argt){value = argt; }
virtual ValueType getValue(){return value; }
ValueType值;
};
int main(){
Base * pt_base = new(Derived< int> {42}); // *错误*
delete pt_base;
}
然而,不会编译。 G ++抱怨:模板占位符类型'Base'后面必须跟一个简单的声明符id ;如果我理解正确,它不会推导出模板参数。
很遗憾,因为我想动态地决定哪个派生类 pt_base
指向(可以是来自 Derived< someType>
或来自类 Derived2< someType2>
)的对象。这样,一个数组或 vector< Base *>
可以存储指向各种派生类的对象的指针。
GCC只有C ++ 17的实验支持,我不有权访问另一个编译器,所以虽然我得到一个编译错误,我不知道我的代码是错误的。你认为什么?
我们如何动态地决定 pt_base
指向一个来自 Derived< someType>
或 Derived2
(所以可以使用多态性)?
或新表达式:
auto p = new派生(42);
或者功能风格的转换:
FOO(导出的(42));
它不适用于声明指针。
您必须简单地提供模板参数,就像您一直需要的那样。或者,我想:
template< class T> Base< T> * downcast(Base< T> * p){return p; }
auto pt_base = downcast(new Derived(42));
According to
https://gcc.gnu.org/projects/cxx-status.html, version 7 of g++, used with flag -std=c++1z
, supports template argument deduction for class templates.
I would expect the following code to compile, especially as Base
is an abstract class, therefore:
1. the compiler knows no instance of Base
can be created;
2. the pointer to base pt_base
points to a clearly defined instance (i.e. Derived<int>{42}
) where the type (int
) is explicit.
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;
}
Yet, it does not compile. G++ complains that "template placeholder type 'Base' must be followed by a simple declarator-id"; if I understand correctly, it does not deduce the template argument.
It's a pity because I would like to dynamically decide which derived class pt_base
points to (could be an object from class Derived<someType>
or from class Derived2<someType2>
). That way, an array or a vector<Base *>
could store pointers to objects of various derived classes.
GCC only has experimental support for C++17 and I don't have access to another compiler, so although I get a compile error I am not sure my code is wrong. What do you think?
And how could we dynamically decide that pt_base
points to an object from either Derived<someType>
or Derived2<someType2>
(so polymorphism can be used)?
Class template argument deduction works for declaring instances of class types:
Derived d(42);
Or new-expressions:
auto p = new Derived(42);
Or function-style casts:
foo(Derived(42));
It does not work for declaring pointers.
You'll have to simply provide the template arguments as you've always had to. Or, I guess:
template <class T> Base<T>* downcast(Base<T>* p) { return p; }
auto pt_base = downcast(new Derived(42));
这篇关于C ++中类模板的模板参数推导17:我做错了吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!