【问题标题】:C++ Compile-Time Conditional Run-Time StatementsC++ 编译时条件运行时语句
【发布时间】:2012-04-18 04:30:10
【问题描述】:

有没有办法在编译时决定两个运行时代码路径之一?我知道函数重载可以用来完成这个壮举,但是代码大小会增加,因为我的两个函数都被编译并链接到程序中。有没有办法避免这种大小的开销?

基本上,我想做的是:

#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_abstract.hpp>

template <class T>
    class X
{
    public:
        void copy_t(T &old_t)
        {
            //
            // if T is abstract, (meaning that t is a pointer)
            //
            t = old_t.clone();

            //
            // else
            //
            t = old_t;
        }   

    private: 
        typename boost::mpl::if_<boost::is_abstract<T>, T *, T>::type t;
};

我知道的唯一方法涉及重载成员函数:

template <class T>
    class X
{   
    public:
        void copy_t(T &old_t)
        {   
            t = make_copy(old_t, t); 
        }   

    private:
        T *make_copy(T &old_t, T *t) 
        {   
            return old_t.clone();
        }   

        T &make_copy(T &old_t, T &t) 
        {   
            return old_t;
        }   

        typename boost::mpl::if_<boost::is_abstract<T>, T *, T>::type t;
};

但是现在,两个make_copy 成员函数被编译并链接到程序中,尽管X 可能只使用抽象类模板参数实例化,在这种情况下,只需要其中一个。

【问题讨论】:

  • 优化器不会删除未调用的函数吗?
  • 让我明确一点:您担心最终可执行文件中单行函数的额外成本?
  • 还要注意你在代码中做了很多假设,例如,每个非抽象类型的对象都是一个完整的对象。 IE。如果您的类型扩展了不同的非抽象类型,并且在中间类型上调用了该函数,那么您将进行切片。您的界面似乎提供了将在每种情况下做最好的事情承诺(复制/克隆),但并不总是兑现承诺。
  • @DavidRodríguez-dribeas 只是想找出做这些事情的正确方法是什么。我不确定我是否理解您的第二条评论 - 非抽象类型的对象怎么可能不完整?可以举个例子吗?
  • 在这种情况下,complete 的反义词是 subobject,而不是 incomplete。该示例是继承层次结构I &lt;- B &lt;- DI 是接口/抽象,B 是非抽象基类,D 是派生类)。您正在执行的检查使IBD 不同,这意味着如果您使用B 实例化模板,则参数将被复制,这将导致切片如果它的实际(complete)类型是D。一个更有趣(也更复杂)的测试是检测clone() 是否存在并采取行动。

标签: c++ template-meta-programming boost-mpl


【解决方案1】:

从您的示例中,函数看起来像是类的成员 模板。如果是这样,它们只会被实例化,如果它们实际上是 用过的;如果重载决议总是选择其中一个,另一个将 永远不会被实例化。

这是许多元编程技术的关键规则。它是 在这种情况下,未实例化的函数并不罕见 如果它被实例化,则会导致编译时错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-18
    相关资源
    最近更新 更多