以下不编译,我该怎么做?我认为这个例子表明了我的意图,但如果人们感到困惑,我会尝试添加一个简介。
template<typename T>
class A
{
private:
struct B
{
template<typename T2>
B& operator=( const A<T2>::B& right ){} // how can I make this work?
};
template<typename T2> friend class A;
template<typename T2> friend class A<T2>::B;
};
最佳答案
您的赋值运算符的基本思想是有缺陷的,即使添加了 typename
,这是一个不可推导的上下文。因此,永远不会推导模板参数,赋值运算符也永远不会工作,除非您明确指定类型,如 B.operator=<some_type>(other_B)
。 .
一个更简单的版本是让它成为一个普通的函数模板,然后 SFINAE 成为你的出路。
#include <type_traits>
template<class> struct is_a_B;
template<class B2>
typename std::enable_if<
is_a_B<B2>::value,
B&
>::type operator=(B2 const& other){
// ...
}
现在剩下的就是 is_a_B
类型特征。您可以通过可能的误报让自己轻松完成此操作:
template<class B>
struct is_a_B{
typedef char yes;
typedef yes (&no)[2];
template<class T>
static yes test(typename T::I_am_a_B_type*);
template<class T>
static no test(...);
static bool const value = sizeof(test<B>(0)) == sizeof(yes);
};
只需提供 I_am_a_B_type
B
中的 typedef类。
Live example on Ideone .注释掉 b1 = 5;
行,它编译为 seen here .
现在是稍微多一些 perverted 没有误报的复杂方式。 :)
template<bool Cond, class OnTrue>
struct and_v{
static bool const value = OnTrue::value;
};
template<class OnTrue>
struct and_v<false, OnTrue>{
static bool const value = false;
};
template<class B>
struct is_a_B{
typedef char yes;
typedef yes (&no)[2];
template<class T>
static yes has_parent(typename T::parent*);
template<class T>
static no has_parent(...);
template<class T>
static yes is_A(A<T>*);
static no is_A(...);
template<class T>
struct lazy_test{
typedef typename std::add_pointer<typename T::parent>::type p_type;
static bool const value = sizeof(is_A(p_type(0))) == sizeof(yes);
};
static bool const value = and_v<sizeof(has_parent<B>(0)) == sizeof(yes),
lazy_test<B>>::value;
};
对于这个你需要一个 typedef A<T> parent;
里面B
.它分为两部分:
- 首先我测试一个
parent
typedef 存在,如果存在 - 如果它实际上是
A
的类型定义类模板。
可悲的是,逻辑运算符( &&
、 ||
、 ?:
)并没有像我希望的那样在模板代码中短路,所以我不得不写那些 and_v
模板 + 一个懒惰的测试器,只有在 parent
时才会被评估typedef 存在。
Live example on Ideone .再次注释掉 b1 = 5;
使其编译为 seen here 的行.
关于c++ - 如何让我的嵌套类进入模板化类以接受自身的其他版本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8857819/