是否有 C++ 模板方法来循环不同的枚举?
Is there a C++ template way to loop on different enums?
在本主题中,我想知道 C++ 方法是否可以在不同的给定枚举上循环?下面的源码是我的提议,但是编译不了。
enum class Fruit : int
{
UNKNOWN = 0,
APPLE = 1
};
enum class Vegetable : int
{
UNKNOWN = 0,
CARROT = 1
};
static const std::map<std::string, Fruit> FRUITS_MAP
{
{"unknown", Fruit::UNKNOWN},
{"apple", Fruit::APPLE}
};
static const std::map<std::string, Vegetable> VEGETABLES_MAP
{
{"unknown", Vegetable::UNKNOWN},
{"carrot", Vegetable::CARROT}
};
template<typename T>
T myFunction(const std::string &iName)
{
T result{T(0)};
if (std::is_same<T, Fruit>::value)
{
const auto &found = FRUITS_MAP.find(iName);
if (FRUITS_MAP.end() != found)
{
result = found->second;
}
}
else if (std::is_same<T, Vegetable>::value)
{
const auto &found = VEGETABLES_MAP.find(iName);
if (VEGETABLES_MAP.end() != found)
{
result = found->second;
}
}
return result;
}
我无法编写仅更改 return 类型的方法,因为我得到 error: ambiguating
您只需在行中添加 constexpr
即可修复您的代码:
if constexpr (std::is_same<T, Fruit>::value)
...
else if constexpr (std::is_same<T, Vegetable>::value)
并像这样使用它:
std::cout << static_cast<int>(myFunction<Fruit>("apple")) << std::endl;
std::cout << static_cast<int>(myFunction<Vegetable>("carrot")) << std::endl;
如果您使用的是十年过时的编译器(为什么?),您可以简单地使用专门的模板:
template<typename T> T myFunction(const std::string &iName);
template<>
Fruit myFunction<Fruit>(const std::string &iName)
{
Fruit result{Fruit(0)};
const auto &found = FRUITS_MAP.find(iName);
if (FRUITS_MAP.end() != found)
{
result = found->second;
}
return result;
}
template<>
Vegetable myFunction<Vegetable>(const std::string &iName)
{
Vegetable result{Vegetable(0)};
const auto &found = VEGETABLES_MAP.find(iName);
if (VEGETABLES_MAP.end() != found)
{
result = found->second;
}
return result;
}
但在这里我们可以问为什么我们需要模板,因为简单地重载不同的名称具有相同的效果。这取决于实际用例。如果你有类型列表,你会带着一些 MTP 的东西走过去,这可能会有所帮助,如果它是将调用给定函数的手工代码,模板的东西就没有意义。
在本主题中,我想知道 C++ 方法是否可以在不同的给定枚举上循环?下面的源码是我的提议,但是编译不了。
enum class Fruit : int
{
UNKNOWN = 0,
APPLE = 1
};
enum class Vegetable : int
{
UNKNOWN = 0,
CARROT = 1
};
static const std::map<std::string, Fruit> FRUITS_MAP
{
{"unknown", Fruit::UNKNOWN},
{"apple", Fruit::APPLE}
};
static const std::map<std::string, Vegetable> VEGETABLES_MAP
{
{"unknown", Vegetable::UNKNOWN},
{"carrot", Vegetable::CARROT}
};
template<typename T>
T myFunction(const std::string &iName)
{
T result{T(0)};
if (std::is_same<T, Fruit>::value)
{
const auto &found = FRUITS_MAP.find(iName);
if (FRUITS_MAP.end() != found)
{
result = found->second;
}
}
else if (std::is_same<T, Vegetable>::value)
{
const auto &found = VEGETABLES_MAP.find(iName);
if (VEGETABLES_MAP.end() != found)
{
result = found->second;
}
}
return result;
}
我无法编写仅更改 return 类型的方法,因为我得到 error: ambiguating
您只需在行中添加 constexpr
即可修复您的代码:
if constexpr (std::is_same<T, Fruit>::value)
...
else if constexpr (std::is_same<T, Vegetable>::value)
并像这样使用它:
std::cout << static_cast<int>(myFunction<Fruit>("apple")) << std::endl;
std::cout << static_cast<int>(myFunction<Vegetable>("carrot")) << std::endl;
如果您使用的是十年过时的编译器(为什么?),您可以简单地使用专门的模板:
template<typename T> T myFunction(const std::string &iName);
template<>
Fruit myFunction<Fruit>(const std::string &iName)
{
Fruit result{Fruit(0)};
const auto &found = FRUITS_MAP.find(iName);
if (FRUITS_MAP.end() != found)
{
result = found->second;
}
return result;
}
template<>
Vegetable myFunction<Vegetable>(const std::string &iName)
{
Vegetable result{Vegetable(0)};
const auto &found = VEGETABLES_MAP.find(iName);
if (VEGETABLES_MAP.end() != found)
{
result = found->second;
}
return result;
}
但在这里我们可以问为什么我们需要模板,因为简单地重载不同的名称具有相同的效果。这取决于实际用例。如果你有类型列表,你会带着一些 MTP 的东西走过去,这可能会有所帮助,如果它是将调用给定函数的手工代码,模板的东西就没有意义。