作者热门文章
- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我已经能够使用我的 previous question 中的可变参数模板取得进一步进展.我现在有一个新问题。在此代码示例中:
#include <iostream>
#include <cstddef>
constexpr std::uint32_t Flag0 = 0x0001;
constexpr std::uint32_t Flag1 = 0x0002;
constexpr std::uint32_t Flag2 = 0x0004;
constexpr std::uint32_t FlagAll = 0xFFFF;
template<std::uint32_t...Cs>
struct flags_tag {constexpr flags_tag(){}; };
template<std::uint32_t...Cs>
struct make_flags{ using type=flags_tag<Cs...>; };
template<std::uint32_t...Cs>
using make_flags_t=typename make_flags<Cs...>::type;
template<std::uint32_t value>
class pValue_t
{
template<std::uint32_t StateMask, class flags>
friend class Compound;
};
template<> class pValue_t<Flag0>
{
public:
pValue_t() :
m_pValue0(reinterpret_cast<void*>(0xFFFFFFFF))
{}
protected:
void* m_pValue0;
};
template<> class pValue_t<Flag1>
{
public:
pValue_t() :
m_pValue1(reinterpret_cast<void*>(0xDEADBEEF))
{}
protected:
void* m_pValue1;
};
template<> class pValue_t<Flag2>
{
public:
pValue_t() :
m_pValue2(reinterpret_cast<void*>(0xCAFEBABE))
{}
protected:
void* m_pValue2;
};
template<std::uint32_t StateMask, class flags>
class Compound;
template<std::uint32_t StateMask, std::uint32_t...Cs>
class Compound< StateMask, flags_tag<Cs...> >:
public pValue_t<Cs>...
{
public:
void print()
{
if (IsStateValid(Flag0))
{
std::cout << this->m_pValue0 << '\n';
}
if ((StateMask & Flag1) == Flag1)
{
std::cout << this->m_pValue1 << '\n';
}
// *** THIS IS THE PROBLEM STATEMENT ***
if (IsStateValid(Flag2))
{
std::cout << this->m_pValue2 << '\n';
}
}
static bool IsStateValid(std::uint32_t stateMask)
{ return ((StateMask & stateMask) == stateMask); }
uint32_t m_stateMask;
};
using my_type = Compound< Flag0 | Flag1, make_flags_t<Flag0, Flag1>>;
int main() {
my_type test;
test.print();
}
print
函数包含对 m_pValue2
的引用,当 StateMask
包含 Flag2
时有效。
现在,编译器警告它无法找到 m_pValue2
。当 StateMask
(在编译时已知)不包含 Flag2
(当 IsStateValid()
为假时)。
具体错误如下:
main.cpp: In instantiation of 'void Compound<StateMask, flags_tag<Cs ...> >::print() [with unsigned int StateMask = 3u; unsigned int ...Cs = {1u, 2u}]':
main.cpp:95:18: required from here
main.cpp:80:27: error: 'class Compound<3u, flags_tag<1u, 2u> >' has no member named 'm_pValue2'
std::cout << this->m_pValue2 << '\n';
我希望这是可能的。在其他模板编程中,我使用 IsStateValid()
编译出与 StateMask
不匹配的代码段。但是,我从未尝试编译掉可能丢失的成员变量。
有没有人有什么想法?
最佳答案
为什么不起作用
无论类型如何,函数模板中的所有分支都将被编译。 IsStateValid(Flag2)
在编译时为 false
并不重要,if
的主体必须是有效代码。由于在那种情况下没有 this->m_pValue2
,这是一个硬错误。
你能做些什么来修复它
您需要将每个打印标志函数转发到一个函数模板,该模板将打印值(如果存在)或不执行任何操作(如果不存在)。我们可以使用函数重载来帮助这里,并确保如果没有这个标志,整个函数将不会被实例化。例如:
void print()
{
printImpl<Flag0>();
printImpl<Flag1>();
printImpl<Flag2>();
}
template <uint32_t F>
void printImpl() {
printImpl<F>(std::is_base_of<pValue_t<F>, Compound>{});
}
template <uint32_t F>
void printImpl(std::true_type ) {
// we DO have this flag
pValue_t<F>::print();
}
template <uint32_t F>
void printImpl(std::false_type ) {
// we do NOT have this flag
// so do nothing
}
此时您需要做的就是添加适当的 print()
。例如:
template<> class pValue_t<Flag2>
{
public:
pValue_t() :
m_pValue2(reinterpret_cast<void*>(0xCAFEBABE))
{}
void print() {
std::cout << m_pValue2 << '\n';
}
protected:
void* m_pValue2;
};
关于C++ 可变参数模板移除函数逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32659299/
我正在做一个项目,我的 android 在这个项目中作为一个网络服务器工作;输入带端口号的 IP 地址,打开 Web 界面,用户可以将文件上传到手机。我想在 Web 界面上显示一些图片,以便我们的界面
我是一名优秀的程序员,十分优秀!