英文:
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
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论