当某物是豆荚时,我试图得到一套行为,而当它不是通过模板元编程时,我试图得到另一种行为。我已经编写了以下代码,但是出现编译错误。我想得到:
yep
nope
但是出现以下编译器错误:
error C2993: 'std::is_pod<_Ty>': illegal type for non-type template parameter '__formal'
使用此代码
#include <iostream>
#include <type_traits>
struct A
{
int b;
};
struct B
{
private:
int b;
public:
int c;
};
template <class Z, std::is_pod<Z>>
void x()
{
std::cout << "yep" << std::endl;
}
template <class Z>
void x()
{
std::cout << "nope" << std::endl;
}
int main()
{
x<A>();
x<B>();
return 0;
}
有什么建议吗?
答案 0 :(得分:4)
您需要在SFINAE上下文中使用std::enable_if
来使用std::is_pod
中的值。看起来像
// only enable this template if Z is a pod type
template <class Z, std::enable_if_t<std::is_pod_v<Z>, bool> = true>
void x()
{
std::cout << "yep" << std::endl;
}
// only enable this template if Z is not a pod type
template <class Z, std::enable_if_t<!std::is_pod_v<Z>, bool> = true>
void x()
{
std::cout << "nope" << std::endl;
}
请注意,std::is_pod
在C ++ 17中已弃用,并已从C ++ 20中删除。
答案 1 :(得分:1)
template <class Z,
std::enable_if_t<std::is_pod<Z>{}, bool> =true
>
void x()
{
std::cout << "yep" << std::endl;
}
这有条件地创建类型为bool
的非类型模板参数,并将其分配为true
。
如果is_pod<Z>{}
为假,则会产生SFINAE失败。
您必须在另一个x
中实现逆条件。
另一种选择是标签分配:
namespace impl {
template <class Z>
void x(std::true_type /* is pod */ )
{
std::cout << "yep" << std::endl;
}
template <class Z>
void x(std::false_type /* is pod */ )
{
std::cout << "nope" << std::endl;
}
}
template<class Z>
void x() {
impl::x<Z>( std::is_pod<Z>{} );
}
,我们使用通常的重载分辨率在两个主体之间进行调度。我个人认为这是最理智的。
答案 2 :(得分:0)
对于c ++ 17,您可以使用if constexpr
(即使简单的if
就足够了,因为两个分支都有效)
template <class Z>
void x()
{
if consexpr (std::is_pod<Z>::value) {
std::cout << "yep" << std::endl;
} else {
std::cout << "nope" << std::endl;
}
}