Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.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++_Icc - Fatal编程技术网

C++ 模板用户定义转换为抽象类引用和英特尔编译器

C++ 模板用户定义转换为抽象类引用和英特尔编译器,c++,icc,C++,Icc,我有以下(非常简化的)“容器”类: 有时,我需要存储从某个抽象类型派生的对象,并对该抽象类型的引用执行相同类型的转换,例如: boost::shared_ptr<some_abstract_type> x(new some_derived_type); container cx = x; ... // user-defined conversion const some_abstract_type &y = cx; // a template conversion us

我有以下(非常简化的)“容器”类:

有时,我需要存储从某个抽象类型派生的对象,并对该抽象类型的引用执行相同类型的转换,例如:

boost::shared_ptr<some_abstract_type> x(new some_derived_type);
container cx = x;

...

// user-defined conversion
const some_abstract_type &y = cx;

// a template conversion using a "getter"
const some_abstract_type &y = cx.get<some_abstract_type>();
另一方面,如果我将
main()
foo()
中的
base
替换为
derived
(或者使用“getter”而不是
foo()
中的类型转换),英特尔也可以正常工作。当
T
是抽象类时,是否有可能说服英特尔编译器使用用户定义的类型转换为引用类型

提前谢谢你的建议


编辑:有趣的是,使用指针类型的类型转换可以很好地工作。如果我加上

template<typename T>
operator T const * () const
{
    return &get<T>();
}

然后它也适用于英特尔。

我会在getter中返回一个指针:

template<typename T>
T const * get() const {
    return boost::any_cast< boost::shared_ptr<T> >(m_content);
}

< > >强> >:<强> >您的问题的添加正好在这个方向上。

< P> OK,所以它似乎是英特尔C++编译器中的一个bug,并被提交到bug跟踪列表中。

我对“代码> ** Boost的推理感到困惑::YANYAXCAST < BooS::SyrdYPPTR>(和MY内容)
>over
*boost::any_cast(m_content)
(或者为什么
m_content
一开始不仅仅是一个
boost::shared_ptr>
,但我猜失去它的原因是因为你的简化);从源代码来看,
any_cast
似乎确实支持
any
对象的按引用传递(请参见)。@JAB实际上有两个
any_cast
的变体,一个是对
any
进行(常量/非常量)引用并返回
T
(因此创建了一个临时变量),一个函数,它获取指向
any
的指针,并返回指向
T
的指针(随后可用于从函数返回对
T
的引用,因为它不会创建
T
的临时实例)。在您引用的情况下,
T
在技术上是
共享的,当您立即取消对共享指针的引用时,除了尝试节省一点点空间/CPU周期外,您没有理由创建额外的指针。(大多数编译器无论如何都会删除副本,因为共享的\u ptr
确实是在该位置临时使用的,不是吗?除非你发现你使用的编译器在这种情况下不执行删除,否则使用指针形式似乎是一种不必要的先发制人优化。)@JAB我明白了,它实际上也很有效。谢谢编辑了这个问题。愚弄揭示了ICC转换为非常量参考。牺牲了一点常量的正确性,你可能有一个可行的解决办法。谢谢你的评论。这就是为什么我提到这个类是“非常简化的”:-)然而,我在这里不明白的是,这就是我的问题(可能有些隐藏)的要点,为什么英特尔编译器没有“看到”当
T
为抽象类型时,用户定义的类型转换为引用类型,而指针类型(抽象/非抽象)的转换不是这种情况。由于我希望避免任何类型的非标准构造,问题可能是我是否做错了什么,或者英特尔编译器中存在错误。我在您的代码中没有看到错误。然而,有时标准的一致性结构并不是每个编译器都支持的。。。
#include <iostream>
#include <boost/any.hpp>
#include <boost/shared_ptr.hpp>

class container
{
    public:

        template<typename T> container(const boost::shared_ptr<T> &rhs)
            : m_content(rhs) { }

        template<typename T>
        operator T const & () const
        {
            return get<T>();
        }

        template<typename T>
        T const & get() const
        {
            return *boost::any_cast< boost::shared_ptr<T> >(m_content);
        }

    private:
        boost::any m_content;
};

class base
{
    public:
        virtual ~base() { }
        virtual void f() const = 0;
};

class derived : public base
{
    public:
        virtual ~derived() { }
        virtual void f() const { std::cout << "hello\n"; }
};

void foo(const container &c)
{
    const base & a = c;
    a.f();
}

int main()
{
    boost::shared_ptr<base> a(new derived);
    container c = a;
    foo(c);
}
test.cpp(44): error: no suitable user-defined conversion from "const container" to "const base" exists
      const base & a = c;
                       ^

compilation aborted for test.cpp (code 2)
template<typename T>
operator T const * () const
{
    return &get<T>();
}
void foo(const container &c)
{
    const base * a = c;
    a->f();
}
template<typename T>
T const * get() const {
    return boost::any_cast< boost::shared_ptr<T> >(m_content);
}
void foo(const container &c)
{
    const base* a = c.get<base>();
    a->f();
}
bool valid() const {
    return m_content != NULL;
}