如何在模板参数中使用 std::is_pod?
How do I use std::is_pod in a template argument?
当某些东西是 pod 时,我试图获得一组行为,而当它不是通过模板元编程时,我试图获得另一组行为。我已经编写了下面的代码,但是出现编译错误。我想得到:
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;
}
有什么建议吗?
您需要使用std::enable_if
才能在 SFINAE 上下文中使用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 中删除。
使用 c++17,您可以使用if constexpr
(即使简单的if
在您的情况下就足够了,因为两个分支都有效(
template <class Z>
void x()
{
if constexpr (std::is_pod_v<Z>) {
std::cout << "yep" << std::endl;
} else {
std::cout << "nope" << std::endl;
}
}
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>{} );
}
我们使用通常的重载分辨率在两个机构之间调度。 我个人认为这是最理智的。
如果您可以使用 C++20,这里有一个使用requires
的解决方案。
template <class Z>
requires std::is_standard_layout_v<Z> && std::is_trivial_v<Z>
void x()
{
std::cout << "yep" << std::endl;
}
相关文章:
- Centos7 g++ "to_string is not in a member of std"
- Where is std::hardware_destructive_interference_size?
- 你如何理解"std: :forward is just syntactic sugar"?这是真的吗?
- What is the std::chrono::time_point equivalent of std::numer
- What is std::vector::_emplace_back_slow_path / std::vector::
- Is std::is_trivially_copyable wrong?
- Why is std::abs(9484282305798401ull) = 9484282305798400?
- What is std::invoke in c++?
- What is std::set::equal_range for?
- Is std::initializer_list{x, y, z} (CTAD) valid?
- Is a log(n) std::find_if possible?
- Is there a std::bytes?
- std::is_nothrow_constructible when constructor is inherited
- IS STD ::功能与使用自动一样有效
- Visual Studio: "str() is not a member of std::ostringstream"
- is compare_exchange_weak for std::shared_ptr broken in msvs
- Matlab's is empty for a std::vector ( C++)
- Is std::make_unique SFINAE-friendly?
- VC++ 2010 "array is not a member of std"错误
- Android NDK chrono epoch is not correct (std::chrono::high_r