问题描述
几天以来,我一直困扰于模板问题,您一次解决了我的每一个问题,所以在此先谢谢您。
I'm stuck with templates problems since few days and you solve each of my problem at a time so thank you in advance.
所以我有一个模板( tl1
)关心 uml组成
和另一个模板( tl2
)是由 uml组成的
所以我的目标是如果组成$ c不编译$ c>对象不是
tl2
的派生的
,如果 typename D
不是派生的 tl1
。
So I've a template (tl1
) who care about a uml composition
, and another template (tl2
) wich is the uml composed
So my goal is to not compile if the composed
object is not a derived
of tl2
and if typename D
is not a tl1 derived
.
遵循此和此我有以下代码:
Following this post and the help of this one I've got the following code:
#include <type_traits>
#include <list>
#include <string>
template <typename T, typename C>
class tl2 ;
template <typename D, typename T>
class tl1 {
private:
static_assert(std::is_base_of<tl2<T, D>, T>::value, "T should inherit from tl2");
std::list<T> mTs ;
tl1() {} ;
friend D ;
public:
T & getTbyName() const ;
};
template <typename T, typename C>
class tl2 {
//static_assert(std::is_base_of<tl1<C, T>, C>::value, "D should inherit from Database");
public:
std::string getName() { return mName ; }
private:
C & mC ;
std::string mName ;
};
class cl1 ;
class cl2 : public tl2<cl2, int> {
};
class cl1 : public tl1<int, cl2> {
};
我的问题是这个编译的很好,我不想。
我不想编译,因为来自 tl1< D,T>
中的 D
从 tl1
导出。
实际上是类cl1:public tl1< int,cl2>
不正确,但可以编译。那么为什么呢?
如果将 cl1
更改为:
My problem is this compile very well and I would like not. I would like not compile because D
from tl1<D, T>
must derived
from tl1
.
And actually class cl1 : public tl1<int, cl2>
is not correct but it compile. So why?
It doesn't compile if I change cl1
to:
class cl1 : public tl1<int, cl2> {
cl1() {}
};
我了解更改后为什么不进行编译,但是我不明白为什么在进行更改之前就进行了编译。
I understand why it doesn't compile after the change, but I do not understand why it compile before.
事实是 tl1
和 tl2
在库中,因此我要在库中执行所有检查。我将无法控制派生,因此我想确保实现
是 tlX派生
。
The fact is tl1
and tl2
will be in library, so I want to perform all checks in the library. I will not have control over derived so I'd like to be sure that implementation
is tlX derived
.
再次感谢您的时间。
昆汀
Thank you for your time again.
Quentin
推荐答案
做您想做的事情的问题是周期性依赖性。就我所知, std :: is_base_of
要求使用完整的类型。
The problem with doing what you are trying to do is cyclical dependencies. std::is_base_of
requires a complete type in order to work as far as I am aware.
您的代码具有tl1中有两个限制。
Your code has TWO restrictions in tl1..
- T必须继承tl2
- D必须继承tl1
最后,它看起来像这样:
In the end, it ends up looking like:
tl1< T,D>
其中D继承 tl1< T,D>
其中D继承 tl1< T ,D>
tl1<T, D>
where D inherits tl1<T, D>
where D inherits tl1<T, D>
换句话说,永远不会定义D,因为Tl1要求将D定义为模板参数,但D必须继承
In other words, D will never be defined because Tl1 requires the definition of D as a template parameter but D must inherit from Tl1 which requires it.
现在,如果您删除了对D的限制,那么由于满足了第一个限制,下面的代码将按需编译。但是,如果取消注释tl1中的static_assert,则它将永远不会编译,因为D的定义取决于tl1的定义,tl1取决于D的定义,依此类推。等等。.
Now if you remove the restriction on D, then the following code will compile as it should because the first restriction is met. However, if you uncomment the static_assert in tl1, it will NEVER compile because the definition of D depends on the definition of tl1 which depends on the definition of D and so on.. and so forth..
您会收到类似这样的错误:
You'd get an error like:
invalid use of incomplete type 'class cl1'
struct is_base_of
^
note: forward declaration of 'class cl1'
代码:
#include <type_traits>
#include <list>
#include <string>
template <typename T, typename C>
class tl2 ;
template <typename D, typename T>
class tl1 {
private:
static_assert(std::is_base_of<tl2<T, D>, T>::value, "T should inherit from tl2");
//static_assert(std::is_base_of<tl1, D>::value, "D should inherit from tl1");
std::list<T> mTs ;
friend D ;
public:
tl1() {}
T & getTbyName() const ;
};
template <typename T, typename C>
class tl2 {
//static_assert(std::is_base_of<tl1<C, T>, C>::value, "D should inherit from Database");
public:
std::string getName() { return mName ; }
private:
//C & mC ;
std::string mName ;
};
class cl1;
class cl2 : public tl2<cl2, cl1> {
public:
cl2() {}
};
class cl1 : public tl1<cl1, cl2> {
public:
cl1() {}
};
int main() {
cl1 a;
cl2 b;
return 0;
}
如果替换 std :: is_base_of
其中:
template<class B, class D>
struct is_base_of
{
template<typename T> struct dummy {};
struct Child : D, dummy<int> {};
static B* Check (B*);
template<class T> static char Check (dummy<T>*);
static const bool value = (sizeof(Check((Child*)0)) == sizeof(B*));
};
它将给您错误:
递归地替换'template< class T>静态字符is_base_of< B,D> :: Check(is_base_of< B,D> :: dummy< T> *)[with T =< missing>]'
在我看来,这更清楚发生了什么。
Which in my opinion is much clearer as to what is happening.
TLDR:您不能。
这篇关于具有模板组成的CRTP编译检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!