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方面。