英文:
How to select a class member using templates
问题
我想将 increase_count 函数有效地编译成 increase_count_apple 和 increase_count_orange。这是另一个类的简化示例,其中这种编译时优化在理论上可以帮助我在运行时。直观地感觉可以使用模板来实现,但我无法得出令人满意的结果。
请注意,这是您要求的代码部分的翻译。
英文:
Consider the example code below.
#include <iostream>
enum class FruitType {
    APPLE,
    ORANGE
};
class Fruit {
    uint64_t apple_count;
    uint64_t orange_count;
public:
    Fruit() : apple_count(0), orange_count(0) {}
    void increase_count(FruitType type) {
        if (type == FruitType::APPLE)
            apple_count++;
        else
            orange_count++;
    }
    void print() {
        std::cout << "apple_count: " << apple_count << std::endl;
        std::cout << "orange_count: " << orange_count << std::endl;
    }
};
int main(int, char**) {
    Fruit fruit;
    fruit.increase_count(FruitType::APPLE);
    fruit.increase_count(FruitType::ORANGE);
    fruit.increase_count(FruitType::APPLE);
    fruit.increase_count(FruitType::APPLE);
    fruit.increase_count(FruitType::ORANGE);
    fruit.print();
    return 0;
}
I want the increase_count function to effectively compile to increase_count_apple and increase_count_orange. This is a simplified example of another class where such compile-time optimisation helps me at runtime, in theory. Intuitively, this feels possible using templates, but I am unable to arrive at a satisfactory output.
答案1
得分: 4
通过将 increase_count 设为一个接受非类型模板参数的模板,你可以做到:
class Fruit {
	uint64_t apple_count;
	uint64_t orange_count;
public:
	Fruit() : apple_count(0), orange_count(0) {}
	template <FruitType type>
	void increase_count() {
		if constexpr (type == FruitType::APPLE)
			apple_count++;
		else
			orange_count++;
	}
	void print() {
		std::cout << "apple_count: " << apple_count << std::endl;
		std::cout << "orange_count: " << orange_count << std::endl;
	}
};
int main(int, char**) {
	Fruit fruit;
	fruit.increase_count<FruitType::APPLE>();
	fruit.increase_count<FruitType::ORANGE>();
	fruit.increase_count<FruitType::APPLE>();
	fruit.increase_count<FruitType::APPLE>();
	fruit.increase_count<FruitType::ORANGE>();
	fruit.print();
	return 0;
}
这将在编译时移除分支,fruit.increase_count<FruitType::APPLE> 实际上调用 increase_count_apple,fruit.increase_count<FruitType::ORANGE>() 调用 increase_count_orange。
英文:
By making increase_count a template that takes a non-type template paramter you can do
class Fruit {
	uint64_t apple_count;
	uint64_t orange_count;
public:
	Fruit() : apple_count(0), orange_count(0) {}
	template <FruitType type>
	void increase_count() {
		if constexpr (type == FruitType::APPLE)
			apple_count++;
		else
			orange_count++;
	}
	void print() {
		std::cout << "apple_count: " << apple_count << std::endl;
		std::cout << "orange_count: " << orange_count << std::endl;
	}
};
int main(int, char**) {
	Fruit fruit;
	fruit.increase_count<FruitType::APPLE>();
	fruit.increase_count<FruitType::ORANGE>();
	fruit.increase_count<FruitType::APPLE>();
	fruit.increase_count<FruitType::APPLE>();
	fruit.increase_count<FruitType::ORANGE>();
	fruit.print();
	return 0;
}
which removes the branch at compile time and fruit.increase_count<FruitType::APPLE> effectively calls increase_count_apple and fruit.increase_count<FruitType::ORANGE>() calls increase_count_orange.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论