这是我的第一次尝试 -
#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
或其他我明确指定为参数而不能为其他人编译的人。这可能吗?
答案 0 :(得分:4)
不,这是不可能的。 p1
和p2
的值是运行时属性,而不是编译时属性,因此编译器不会知道&#34;他们在编译时的价值观。
您可以使用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
}
答案 1 :(得分:3)
您可以将p
更改为模板参数,然后使用std::enable_if
,如下所示:
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
}
对于p1
和p2
,constexpr
关键字可确保我们可以将变量用作模板参数。
如果您以后想要其他退货类型,例如int
,请使用:
std::enable_if_t<p == props::left, int>
答案 2 :(得分:1)
正如其他答案建议使用模板参数一样,我还会添加一个答案,说明如何使用标记调度(description from boost.org)来实现这一点:
#include <iostream>
using namespace std;
struct props
{
struct left {};
struct right {};
};
void allowLeftOnly(props::left p)
{
cout << "Wow!";
}
int main()
{
allowLeftOnly(props::left{});
// allowLeftOnly(props::right{}); // Fails to compile
}