Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;动态检测参数类并将其转换为_C++_C++11_Operator Overloading - Fatal编程技术网

C++ C++;动态检测参数类并将其转换为

C++ C++;动态检测参数类并将其转换为,c++,c++11,operator-overloading,C++,C++11,Operator Overloading,我有两个类,一个继承自另一个。基类的相关部分如下所示(很明显,这个类有ctor、dtor等,特别是操作符[],但我认为这些与手头的问题无关): #包括 模板 类向量 { 公众: 模板友元向量运算符+(常量向量&,常量向量&); 模板friend std::ostream&operator&); }; 派生类(同样,显然我已经去掉了那些我认为不相关的部分): #包括“Vector.h” 模板 类多项式 :公共向量 { 公众: 模板friend std::ostream&operator&); }

我有两个类,一个继承自另一个。基类的相关部分如下所示(很明显,这个类有ctor、dtor等,特别是
操作符[]
,但我认为这些与手头的问题无关):

#包括
模板
类向量
{
公众:
模板友元向量运算符+(常量向量&,常量向量&);
模板friend std::ostream&operator&);
};
派生类(同样,显然我已经去掉了那些我认为不相关的部分):

#包括“Vector.h”
模板
类多项式
:公共向量
{
公众:
模板friend std::ostream&operator&);
};
(注意:friend函数在模板中使用的字母与类不同,因为gcc在其他情况下会抱怨“隐藏”。不过,逻辑是相同的。)

Vector
s单向打印(例如
<3,5,1>
)<代码>多项式s打印另一个(例如
3x^2+5x+1

不过,这会引起一个问题。当我将两个
多项式
s相加时,编译器使用
模板Vector操作符+(const Vector&,const Vector&)
,它当然返回一个
向量
。因此,如果我尝试执行类似
std::cout Vector操作符+(const Vector&,const Vector&)
这样的操作,它将检测其参数的实际数据类型,并相应地转换返回值(例如,如果向其传递两个
多项式,则返回一个
多项式。如果可能的话,我想这样做,而不需要
操作符+
了解
向量的每个可能的子类(我认为这可能是一个合理的愿望?),也不需要为每个子类创建新的
操作符+
函数(因为我还有其他几个重载运算符,并且希望避免为每个派生类复制几乎完全相同的代码十次)


< P>我知道Python中这是可能的(事实上比较容易)。C++支持这样的事情吗?< /P> < P>如果计算结果为<代码>向量< /代码>,你不能简单地(合法地)将其转换为
多项式
。为了达到预期效果,您需要一些更深入的修改。您需要一个免费的
运算符+
,一个可以提供预期结果类型的实现,以及一种检测从
向量
派生的所有内容的方法。让我们构建它

a) 检测所有
向量

为此,您可以从空基类派生,该空基类将通过空基类优化(EBO)进行优化,如果
std::enable\u

struct VectorBase {};

template< class T, unsigned int N >
class Vector
{
  // ...
};
应替换为:

template< class T, unsigned int N >
class Vector
{
    friend Vector< T, N > operator+ ( const Vector< T, N >&, const Vector< T, N >& );
};

减去一些小的打字错误(我还没有测试过),这个策略应该适合你。

谢谢你的回答!我在这里看到了一些我不熟悉的代码,所以我会做一些研究。@Arandur:我承认这是非常先进的,但我看不到更简单的方法。另外,请注意,代码使用了C++11功能,因此您需要一个支持它的编译器,并且通常还需要显式启用C++11。好吧,这是一个非常神奇的功能,但它的工作方式很有魅力!再次感谢你的回答。是的,我一直在使用C++11的特性,所以这对我来说很有用。谢谢
struct VectorBase {};

template< class T, unsigned int N >
class Vector
{
  // ...
};
template< class T, unsigned int N >
class Vector
{
    template < class U, unsigned int M >
    friend Vector< U, M > operator+ ( const Vector< U, M >&, const Vector< U, M >& );
};
template< class T, unsigned int N >
class Vector
{
    friend Vector< T, N > operator+ ( const Vector< T, N >&, const Vector< T, N >& );
};
template< class T, unsigned int N >
class Vector
{
public:
    template< typename R >
    static R add( const Vector< T, N >& lhs, const Vector< T, N >& rhs )
    {
        static_assert( std::is_base_of<VectorBase,R>::value,
                       "R needs to be derived from Vector<T,N>" );
        R result;
        // implement it here...
        return result;
    }
};
// as a free function:
template< typename V >
typename std::enable_if< std::is_base_of< VectorBase, V >::value, V >::type
operator+( const V& lhs, const V& rhs )
{
  return V::template add<V>( lhs, rhs );
}