【发布时间】:2014-08-27 23:13:10
【问题描述】:
问题
我有以下两个结构声明:
template <typename T>
struct Yin {
T *m_ptr;
};
template <typename T>
struct Yang {
T *m_ptr;
};
我想找到 X 和 Y 以便在替换后得到类似的东西:
// Not real C++ syntax
struct Yin<X> {
Yang<Y> *m_ptr;
}
struct Yang<Y> {
Yin<X> *m_ptr;
};
但我不想将Yin 和Yang 硬编码到彼此的定义中,所以X 会类似于Yin<Yang<Yin<Yang<...>>>>。
我可以在没有模板参数的情况下做到这一点,例如:
struct Yin;
struct Yang;
struct Yin {
Yang *m_ptr;
};
struct Yang {
Yin *m_ptr;
};
但我的实际用例要复杂得多,我真的很想把它变成通用的。有谁知道实现这一目标的方法?或者也许会看到我遗漏的明显东西?
我已将此问题标记为c++14,因为我正在使用带有-std=c++1y 的clang 编译相关代码,并且我很高兴使用任何c++11/c++14 功能来完成这项工作。
一个无法编译的潜在解决方案。
这是一个看起来应该可以工作但无法编译的解决方案(并且给了我无用的错误消息):
template <typename T>
struct Yin {
T *m_ptr;
};
template <typename T>
struct Yang {
T *m_ptr;
};
template <template <class> class A, template <class> class B>
struct knot {
using type = A<typename knot<B, A>::type>;
};
template <template <class> class A, template <class> class B>
using Tie = typename knot<A, B>::type;
int main() {
// foo.cc:13:39: error: no type named 'type' in 'knot<Yin, Yang>'
// using type = A<typename knot<B, A>::type>;
// ~~~~~~~~~~~~~~~~~~~~~^~~~
Tie<Yin, Yang> x;
}
【问题讨论】:
-
考虑到正确的
X和Y将有无限的级别,我不明白如果没有明确的专业化怎么可能。 -
差不多,使用额外的继承级别:coliru.stacked-crooked.com/a/4e5d8300be418a6e
-
@dyp 不错!继承很聪明。编辑:嗯..我误解了。这不太行。虽然很近!
-
我无法让它真正使用这些类型,只有通过这种额外的继承级别。但是,我可以使
foo和bar类型兼容:coliru.stacked-crooked.com/a/c6c3c0a6a6391c56 -
我得到了这个:coliru.stacked-crooked.com/a/bcd9aa67b40df386,这是正确的想法吗?可能想添加一些 SFINAE 这样它就不会意外拾取误报,但我认为这很好......