C++ 将函数参数限制为某些枚举值
这是我的第一次尝试-C++ 将函数参数限制为某些枚举值,c++,c++11,templates,c++14,c++17,C++,C++11,Templates,C++14,C++17,这是我的第一次尝试- #include <iostream> using namespace std; enum class props { left, right }; template<typename T> auto allowLeftOnly(T p) -> decltype((p==props::left), void()) { cout << "Wow!"; } int main() { props p1 = p
#include <iostream>
using namespace std;
enum class props {
left, right
};
template<typename T>
auto allowLeftOnly(T p) -> decltype((p==props::left), void())
{
cout << "Wow!";
}
int main() {
props p1 = props::left;
props p2 = props::right;
allowLeftOnly(p1);
// allowLeftOnly(p2); // should fail to compile
}
我希望allowLeftOnly函数只接受props::left或其他我显式指定为参数且无法为其他参数编译的参数。那可能吗?不,不可能。p1和p2的值是运行时属性,而不是编译时属性,因此编译器在编译时不知道它们的值 您可以在编译时使用constexpr使它们为人所知,并将它们作为模板参数传递,例如:
#include <iostream>
#include <type_traits>
enum class props {
left, right
};
template <props v>
typename std::enable_if<v == props::left, void>::type allowLeftOnly()
{ std::cout << "Wow!\n"; }
int main() {
constexpr auto p1 = props::left;
constexpr auto p2 = props::right;
allowLeftOnly<p1>();
allowLeftOnly<p2>(); // Fails to compile
}
不,这是不可能的。p1和p2的值是运行时属性,而不是编译时属性,因此编译器在编译时不知道它们的值 您可以在编译时使用constexpr使它们为人所知,并将它们作为模板参数传递,例如:
#include <iostream>
#include <type_traits>
enum class props {
left, right
};
template <props v>
typename std::enable_if<v == props::left, void>::type allowLeftOnly()
{ std::cout << "Wow!\n"; }
int main() {
constexpr auto p1 = props::left;
constexpr auto p2 = props::right;
allowLeftOnly<p1>();
allowLeftOnly<p2>(); // Fails to compile
}
您可以将p in更改为模板参数,然后在以下情况下使用std::enable\u:
template <props p> // p is now a template parameter
std::enable_if_t<p == props::left> // We only allow p == props::left, return type is implicitly void
allowLeftOnly() // No 'normal' parameters anymore
{
std::cout << "Wow!";
}
int main()
{
constexpr props p1 = props::left;
constexpr props p2 = props::right;
allowLeftOnly<p1>();
// allowLeftOnly<p2>(); // Fails to compile
}
您可以将p in更改为模板参数,然后在以下情况下使用std::enable\u:
template <props p> // p is now a template parameter
std::enable_if_t<p == props::left> // We only allow p == props::left, return type is implicitly void
allowLeftOnly() // No 'normal' parameters anymore
{
std::cout << "Wow!";
}
int main()
{
constexpr props p1 = props::left;
constexpr props p2 = props::right;
allowLeftOnly<p1>();
// allowLeftOnly<p2>(); // Fails to compile
}
正如其他答案建议使用模板参数一样,我还将添加一个答案,说明如何使用标记分派来实现这一点:
正如其他答案建议使用模板参数一样,我还将添加一个答案,说明如何使用标记分派来实现这一点:
您必须将p作为模板参数来执行您想要执行的操作。您想要用此解决方案解决的实际问题是什么?你为什么要这样做?请花些时间阅读并思考您的问题是如何成为一个例子的。@有些程序员不想解决任何实质性的问题,试图学习c++的TMP方面,您必须使p成为一个模板参数来完成您想做的事情。您想用此解决方案解决的实际问题是什么?你为什么要这样做?请花些时间阅读并思考你的问题是如何举例的。@一些程序员不试图解决任何实质性的问题,试图学习C++的TMP方面。