用于识别模板类中的类的元函数出现问题
Trouble with metafunction for identifying class-within-template-class
我有以下结构的代码:
template <typename T>
struct Foo
{
struct Bar
{
int data;
};
};
我想写元函数来告诉我一个类型是Foo还是Bar。 第一个很简单:
template <typename T>
struct is_foo : boost::mpl::false_
{};
template <typename T>
struct is_foo<Foo<T> > : boost::mpl::true_
{};
...
BOOST_MPL_ASSERT(( is_foo<Foo<int> > ));
BOOST_MPL_ASSERT_NOT(( is_foo<int> ));
但是,相同的方法不适用于 Bar:
template <typename T>
struct is_bar : boost::mpl::false_
{};
template <typename T>
struct is_bar<typename Foo<T>::Bar> : boost::mpl::true_
{};
编译器拒绝此代码。 海湾合作委员会 说:
main.cpp:38:8: error: template parameters not used in partial specialization:
main.cpp:38:8: error: ‘T’
奇怪的是,clang 会编译代码,但它会发出警告并且元函数不起作用(总是 false):
main.cpp:38:8: warning: class template partial specialization contains a template parameter that can not be deduced;
this partial specialization will never be used
struct is_bar<typename Foo<T>::Bar> : boost::mpl::true_
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:37:20: note: non-deducible template parameter 'T'
template <typename T>
^
此问题是否有解决方法? 特定于 c++11 的解决方案就可以了。
这是使用TTI(http://svn.boost.org/svn/boost/sandbox/tti)对我自己的问题的一个非常不优雅的解决方案:
首先,添加一个虚拟标签到栏:
template <typename T>
struct Foo
{
struct Bar
{
typedef void i_am_bar;
int data;
};
};
接下来,使用 TTI 检查该标记:
BOOST_TTI_HAS_TYPE(i_am_bar);
template <typename T>
struct is_bar : boost::tti::has_type_i_am_bar<T>
{};
...
BOOST_MPL_ASSERT(( is_bar<Foo<int>::Bar> ));
BOOST_MPL_ASSERT_NOT(( is_bar<Foo<int> > ));
BOOST_MPL_ASSERT_NOT(( is_bar<int> ));
可以肯定的是,这很糟糕,但它满足了我的用例。
问题是T
是类型Foo<T>::Bar
名称的一部分,但它不是类型结构的一部分。
一个可能的解决方案是在类型的结构中对T
进行编码:
template<typename Outer, typename Inner> struct Nested: public Inner {
using Inner::Inner;
};
template<typename T> struct Foo {
struct BarImpl {
int data;
};
using Bar = Nested<Foo<T>, BarImpl>;
};
template <typename T> struct is_bar: std::false_type {};
template <typename T, typename U> struct is_bar<Nested<Foo<T>, U>>:
std::is_same<typename Foo<T>::Bar, Nested<Foo<T>, U>> {};
测试:
static_assert(is_bar<Foo<int>::Bar>::value, "!");
static_assert(!is_bar<Foo<int>>::value, "!");
static_assert(!is_bar<int>::value, "!");
编译器
是正确的,简单易懂的解释是:他们只是不想替换所有可能的类型,T
只是为了意识到给定模板中是否有嵌套类型栏。您可以在一本关于模板的"经典"(我希望也是众所周知的)书中找到更精确的解释:"C++模板 - 完整指南"。
幸运的是,C++11可以帮助您做得更好! :)
#include <type_traits>
template <typename T>
struct has_nested_bar
{
template <typename W>
struct wrapper {};
template <typename C>
static std::true_type check(
const wrapper<C>*
, const typename C::Bar* = nullptr
);
template <class C>
static std::false_type check(...);
constexpr static bool value = std::is_same<
decltype(check<T>(nullptr))
, std::true_type
>::type::value;
typedef std::integral_constant<bool, value> type;
};
这个元函数将检查给定类型是否嵌套Bar
类型(据我所知,这是您is_bar
的初始意图)。
template <typename T>
struct Foo
{
struct Bar
{
int data;
};
};
struct Bar {};
int main()
{
std::cout << has_nested_bar<Foo<int>>::value << std::endl;
std::cout << has_nested_bar<Bar>::value << std::endl;
return 0;
}
将输出:
zaufi@gentop /work/tests $ ./has-nested-bar
1
0
稍后您可以将此元函数与is_foo
结合使用,以检查嵌套Bar
是否确实在Foo
内......
相关文章:
- 类C++中的函数问题(LNK2019和LNK1120错误)
- 返回不停止函数,递归函数问题?(编程练习,动态规划,Levenshtein 回溯)
- 变分模板递归构造函数问题
- C++函数问题中的数组分配
- C++中嵌套在另一个 LinkedList 中的 LinkedList 整数上的回调函数问题
- C++重载构造函数问题
- 二叉搜索树析构函数问题
- C++ vector<pair<int,int>> std::all_of() 函数问题(重定向到头文件)
- 迷宫构造函数问题 [线程 1:EXC_BAD_ACCESS(代码 = 1,地址 = 0x8)]
- C++函数问题中的 IF 语句
- 函数问题,未定义的引用错误
- C++ 指针无效函数问题
- C++函数问题 = 帮助我理解基本概念
- 由于基于接口的编程,遇到 C++ 虚拟模板函数问题
- C++二进制树递归析构函数问题
- 构造函数问题<无法读取内存>
- 构造函数问题
- C 时间函数问题
- 另一个类中的类的构造函数问题
- C与C++函数问题