Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/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+;中模板的所有实例生成的单个机器代码实例+;:是否可行和/或可能?_C++_Templates_Theory_Compiler Optimization - Fatal编程技术网

C++ 为C+;中模板的所有实例生成的单个机器代码实例+;:是否可行和/或可能?

C++ 为C+;中模板的所有实例生成的单个机器代码实例+;:是否可行和/或可能?,c++,templates,theory,compiler-optimization,C++,Templates,Theory,Compiler Optimization,我一直在思考这个问题,我想我在什么地方读到过,但我再也找不到更多关于这个问题的信息了 仅出于理论而非实际目的,生成一个能够处理此类模板的所有实例的单个模板实例是否可能、可行和/或实用?有没有编译器能够做到这一点 例如,考虑这个类模板… template<typename T> class UselessCalculator { private: T result; public: UselessCalculator() : res

我一直在思考这个问题,我想我在什么地方读到过,但我再也找不到更多关于这个问题的信息了

仅出于理论而非实际目的,生成一个能够处理此类模板的所有实例的单个模板实例是否可能、可行和/或实用?有没有编译器能够做到这一点

例如,考虑这个类模板…

template<typename T>
class UselessCalculator {
    private:
        T   result;

    public:
        UselessCalculator() : result(0) {}

        UselessCalculator &operator=(T what) {
            this->result = what;
            return *this;
        }

        UselessCalculator &operator+=(T what) {
            this->result += what;
            return *this;
        }

        UselessCalculator &operator-=(T what) {
            this->result -= what;
            return *this;
        }

        UselessCalculator &operator*=(T what) {
            this->result *= what;
            return *this;
        }

        UselessCalculator &operator/=(T what) {
            this->result /= what;
            return *this;
        }
};
现在,编译器必须为每个
UselessCalculator
“实例化”的唯一内容是
VirtualTable
和助手函数(如果有的话)。例如,
UselessCalculator
将转换为

#define real(what) ((int*)what)

void constructInt(void *this, int what) {
    *real(this) = what;
}

void copyConstruct(void *this, const void *what) {
    *real(this) = *real(what);
}

void moveConstruct(void *this, void *what) {
    *real(this) = *real(what);
}

void destruct(void *this) {}

void operatorAddAssign(void *this, const void *what) {
    *real(this) += *real(what);
}


void operatorSubtractAssign(void *this, const void *what) {
    *real(this) -= *real(what);
}


void operatorMultiplyAssign(void *this, const void *what) {
    *real(this) *= *real(what);
}


void operatorDivideAssign(void *this, const void *what) {
    *real(this) /= *real(what);
}
然后,考虑到这一点

int main() {
    UselessCalculator<int> myUselessCalc;
    myUselessCalc += 10;
    myUselessCalc *= 10;
    myUselessCalc -= 10;
    myUselessCalc /= 10;
}

VirtualTable virtualTableInt = {
    &someFunkyImplementationOfStdTypeInfoForInt,
    constructInt,
    copyConstruct,
    moveConstruct,
    destroy,
    addAssign,
    subtractAssign,
    multiplyAssign,
    divideAssign
    };
我知道这将超越模板的所有用途,很多人不会喜欢这个想法(我不喜欢它,我只是好奇),而且代码的效率可能会更低,无论是CPU还是内存方面,更不用说它几乎无法优化,它们也不再是“模板”。但其他人在过去对它们的虐待更严重,不是吗顺便说一句,最好有一个开关来禁用它,如果有必要的话,因为模板元编程将变得几乎无用


所以,我的问题是,如果还不够清楚,所有这些混乱是否可行、实用、可实施?一些工具链是否成功地做到了这一点?它能提供比其明显的开销更大的好处吗?

好吧,你基本上是在问一些编译器是否能通过运行时多态性(“带有虚拟函数的经典”OOP)来实现通常所说的“编译时多态性”(C++模板)

虽然这在理论上是可能的(至少在一定程度上是可能的),但它确实违背了语言设计原则。在编译时多态性更合适的上下文中,模板是作为运行时多态性的有效替代品提供的。模板的全部目的是不同于“普通”运行时多态性。许多模板特性在很大程度上取决于它们的编译时性质

其思想是,如果使用模板,就意味着需要编译时多态性,而不是运行时多态性


这是奖牌的一面。另一方面,编写糟糕的模板代码可能会导致不必要的代码膨胀,因为在运行时多态性可以很容易地以更少的代码膨胀和可忽略的性能损失实现同样的目标的情况下,会强制编译时多态性(即重复实例化相同的代码)。从这个角度来看,在模板代码中隐式地自动切换到运行时多态性可能是有益的。但我相信,目前的语言并不是专门针对这一点而设计的。这是需要您自己显式完成的事情。

AFAIK,这就是Java实现其“泛型”(即模板)的方式:隐式使用运行时多态性。
int main() {
    UselessCalculator<int> myUselessCalc;
    myUselessCalc += 10;
    myUselessCalc *= 10;
    myUselessCalc -= 10;
    myUselessCalc /= 10;
}

VirtualTable virtualTableInt = {
    &someFunkyImplementationOfStdTypeInfoForInt,
    constructInt,
    copyConstruct,
    moveConstruct,
    destroy,
    addAssign,
    subtractAssign,
    multiplyAssign,
    divideAssign
    };
struct UselessCalculatorInt {
    int result;
};

int main() {
    int tmpStorage;

    UselessCalculatorInt myUselessCalc;
    UselessCalculatorConstruct(&virtualTableInt, &myUselessCalc);

    tmpStorage = 10;
    UselessCalculatorAddAssign(&virtualTableInt, &myUselessCalc, &tmpStorage);

    tmpStorage = 10;
    UselessCalculatorSubtractAssign(&virtualTableInt, &myUselessCalc, &tmpStorage);

    tmpStorage = 10;
    UselessCalculatorMultiplyAssign(&virtualTableInt, &myUselessCalc, &tmpStorage);

    tmpStorage = 10;
    UselessCalculatorDivideAssign(&virtualTableInt, &myUselessCalc, &tmpStorage);

    UselessCalculatorDestroy(&virtualTableInt, &myUselessCalc);
    return 0;
}