C ++中类模板的模板参数推导17:我做错了吗? [英] Template argument deduction for class templates in C++17: am I doing it wrong?

查看:713
本文介绍了C ++中类模板的模板参数推导17:我做错了吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据
https://gcc.gnu.org/projects /cxx-status.html ,与标记 -std = c ++ 1z 一起使用的g ++版本7支持类模板的模板参数推导。 p>

我期望编译下面的代码,特别是 Base 是一个抽象类,因此:

1.编译器知道可以创建 Base 的实例;

2.指向base pt_base 指向一个明确定义的实例(即 Derived {42} ),其中类型( int

 模板< 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆