0

这更多是关于 C++ 编译器如何处理 const typeid 调用的问题。

你好!我正在尝试创建一个元组样式的类,其配置方式使我不必重写一堆具有专业化的代码。

所以这是一般的想法:

struct null_type{};

template <typename T1,typename T2=null_type,typename T3=null_type>
class ptestclass
{
private:
    template<typename K1,typename K2,typename K3>
    class barclass
    {
    public:
        static inline void bar(std::tuple<K1,K2,K3>& vals,K1* otherval1,K2* otherval2,K3* otherval3)
        {
            Foo(tr1::get<0>(vals),*otherval1);
            Foo(tr1::get<1>(vals),*otherval2);
            Foo(tr1::get<2>(vals),*otherval3);
        }
    };
    template<typename K1,typename K2>
    class barclass<K1,K2,null_type>
    {
    public:
        static inline void bar(std::tuple<K1,K2,null_type>& vals,K1* otherval1,K2* otherval2,null_type* otherval3)
        {
            Foo(tr1::get<0>(vals),*otherval1);
            Foo(tr1::get<1>(vals),*otherval2);
        }
    };
    template<typename K1>
    class barclass<K1,null_type,null_type>
    {
    public:
        static inline void bar(std::tuple<K1,null_type,null_type>& vals,K1* otherval1,null_type* otherval2,null_type* otherval3)
        {
            Foo(tr1::get<0>(vals),*otherval1);
        }
    };

    /*
     *Old Bar function...much more readable than bar class, but you cannot partially specialize
     *member functions of a class
     *
    void inline bar(std::tuple<T1,T2,T3> otherval)
    {
        if (typeid(T1) != typeid(null_type))//constant check hopfully optomized out
        {
            Foo(vals.get(1),otherval.get(1));
        }
        if (typeid(T2) != typeid(null_type))//constant check hopfully optomized out
        {
            Foo(vals.get(2),otherval.get(2));
        }
        if(typeid(T3) != typeid(null_type))//constant check hopfully optomized out
        {
            Foo(vals.get(3),otherval.get(3));
        }

    }
     */
    std::tuple<T1,T2,T3> vals;



    template<typename K>
    void static inline Foo(K& val,K& otherval)
    {
        //inlineable, short function that is called many (millions) of times per iteration
        val += otherval;
    }

    template<>
    void inline Foo<null_type>(null_type& val,null_type& otherval)
    {
        //inlineable, short function that is called many (millions) of times per iteration
        throw "Foo called on null type";
    }

public:
    ptestclass()
    {
        printf("made object");
    }
    void one_iteration(T1* otherval1,T2* otherval2,T3* otherval3,size_t count)
    {
        for (int i = 0; i < count; ++i)
        {
            barclass<T1,T2,T3>::bar(vals,otherval1+i,otherval2+i,otherval3+i);
        }
    }
};

//exposed public class with specialized one_iteration interfaces
template <typename T1,typename T2=null_type,typename T3=null_type>
class testclass : public ptestclass<T1,T2,T3>
{
public:
    void one_iteration(T1* otherval1,T1* otherval2,T1* otherval3,size_t count)
    {
        ptestclass::one_iteration(otherval1,otherval2,otherval3,count);
    }
};

template <typename T1>
class testclass<T1,null_type,null_type> : public ptestclass<T1,null_type,null_type>
{
public:
    void one_iteration(T1* otherval1,size_t count)
    {
        ptestclass::one_iteration(otherval1,NULL,NULL,count);
    }
};

所以我的问题是这种优化甚至可以在 C++ 中实现吗?如果不是这样,对我来说,在子节点上使用继承模型而不是这个级别的模板可能更有意义。但是,我试图避免不断检查指定类型的数量和间接成本。

我将开始深入研究程序集,看看编译器是否这样做......以防这不是标准化的行为,我正在使用 Microsoft Visual C++ Compiler 10.0。

4

1 回答 1

1

我想我在发表之前的评论时误解了你的问题。

假设你可以使用 c++11,或者你可以使用 boost,你可以使用类似的东西!std::is_same< T1, null_type >::value /*or boost::is_same...*/而不是 typeid(T1) != typeid(null_type)。这使用 TMP 解析为编译时常量,大多数编译器都可以轻松优化掉它。

这更多是关于 C++ 编译器如何处理 const typeid 调用的问题。

我没有回答这个具体问题,但如果我了解您实际在寻找什么,以上内容就足够了。

于 2013-03-19T18:48:01.900 回答