创建一个元组样式类来优化未使用的部分

时间:2013-03-19 15:20:49

标签: c++ templates typeid

这更像是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 ++编译器10.0。

1 个答案:

答案 0 :(得分:1)

当我提出我之前的评论时,我想我误解了你的问题。

假设您可以使用c ++ 11,或者您可以使用boost,您可以使用!std::is_same< T1, null_type >::value /*or boost::is_same...*/而不是typeid(T1)!= typeid(null_type)。这使用TMP解析为编译时常量,大多数编译器都可以毫无困难地进行优化。

  

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

我没有回答这个具体问题,但如果我明白你实际上在寻找什么,那么上述就足够了。