延迟成员变量类型定义,直到另一个 class 从它继承
Delay a member variables type definition till another class inherits from it
我正在尝试将成员变量类型声明为派生 class 控制的东西 - 而无需将类型作为模板传输。
#include <tuple>
#include <iostream>
#include <ostream>
using namespace std;
template<class DERIVED_TYPE>
struct haveChildren
{
const std::tuple<int, DERIVED_TYPE::innerContext > myChildren;
haveChildren(int a, char b) : myChildren(5, DERIVED_TYPE::innerContext{ a, b }) {}
friend ostream& operator<< (ostream& streamReceiver, const haveChildren<DERIVED_TYPE>& streamSender)
{
int myInt; int myChar;
std::tie(myInt, myChar) = std::get<1>(streamSender.myChildren);
return streamReceiver << "My int is " << myInt << " my char is " << ((char)myChar);
}
};
struct haveChildrenCharAndInt : public haveChildren<haveChildrenCharAndInt>
{
typedef std::tuple<char, int> innerContext;
haveChildrenCharAndInt() : haveChildren<haveChildrenCharAndInt>(10,'x') {}
};
int main(int argc, char* argv[])
{
cout << haveChildrenCharAndInt();
return 0;
}
那当然不会编译-但我希望你明白我想做什么。
可以通过像这样将类型作为模板参数传递来完成:
template<class DERIVED_TYPE,typename A,typename B>
struct haveChildren
{
const std::tuple<int, std::tuple<A, B> > myChildren;
haveChildren(int a, char b) : myChildren(5, std::tuple<A, B> { a, b }) {}
friend ostream& operator<< (ostream& streamReceiver, const haveChildren<DERIVED_TYPE,A,B>& streamSender)
{
int myInt; int myChar;
std::tie(myInt, myChar) = std::get<1>(streamSender.myChildren);
return streamReceiver << "My int is " << myInt << " my char is " << ((char)myChar);
}
};
struct haveChildrenCharAndInt : public haveChildren<haveChildrenCharAndInt,char,int>
{
typedef std::tuple<char, int> innerContext;
haveChildrenCharAndInt() : haveChildren<haveChildrenCharAndInt,char,int>(10,'x') {}
};
int main(int argc, char* argv[])
{
cout << haveChildrenCharAndInt();
return 0;
}
但是这个解决方案并不好,因为 class 作为成员变量应该具有的类型是 classes 并且它们是在之后创建的。
你们有没有人知道一种设计或技巧,可以让一个类型的成员变量在 class 从它继承之前没有定义 - 而不将类型作为模板参数传递?
您可以稍微改变您的设计并使其正常工作。
#include <tuple>
#include <iostream>
#include <ostream>
using namespace std;
// A helper class template to let you define the inner
// context of a derived type before the derived type is
// defined.
template <class DERIVED_TYPE> struct InnerContext;
template<class DERIVED_TYPE>
struct haveChildren
{
// Use the helper class template to get the inner context
// type of DERIVED_TYPE.
using DerivedInnerContext = typename InnerContext<DERIVED_TYPE>::type;
std::tuple<int, DerivedInnerContext> myChildren;
haveChildren(int a, char b) : myChildren(5, DerivedInnerContext{ a, b }) {}
friend ostream& operator<< (ostream& streamReceiver, const haveChildren& streamSender)
{
int myInt; int myChar;
std::tie(myInt, myChar) = std::get<1>(streamSender.myChildren);
return streamReceiver << "My int is " << myInt << " my char is " << ((char)myChar);
}
};
// Define the inner context of haveChildrenCharAndInt before
// haveChildrenCharAndInt is defined.
struct haveChildrenCharAndInt;
template <> struct InnerContext<haveChildrenCharAndInt>
{
using type = std::tuple<char, int>;
};
// haveChildrenCharAndInt is now simplified.
struct haveChildrenCharAndInt : public haveChildren<haveChildrenCharAndInt>
{
haveChildrenCharAndInt() : haveChildren<haveChildrenCharAndInt>(10,'x') {}
};
int main(int argc, char* argv[])
{
cout << haveChildrenCharAndInt();
return 0;
}
您可以将内部上下文作为类型特征进行传输:
template<typename Type>
struct inner_context;
并在基础 class 中使用它作为:
template<class Derived>
struct base {
using children_type = typename inner_context<Derived>::type;
const std::tuple<int, children_type> children;
base(int a, char b) : children(5, children_type{ a, b }) {}
};
然后每当你定义一个新类型时,你就声明了该类型的特化:
struct derived;
template<>
struct inner_context<derived> {
using type = std::tuple<char, int>;
};
最后是类型本身:
struct derived : public base<derived> {
derived() : base(10,'x') {}
};
我正在尝试将成员变量类型声明为派生 class 控制的东西 - 而无需将类型作为模板传输。
#include <tuple>
#include <iostream>
#include <ostream>
using namespace std;
template<class DERIVED_TYPE>
struct haveChildren
{
const std::tuple<int, DERIVED_TYPE::innerContext > myChildren;
haveChildren(int a, char b) : myChildren(5, DERIVED_TYPE::innerContext{ a, b }) {}
friend ostream& operator<< (ostream& streamReceiver, const haveChildren<DERIVED_TYPE>& streamSender)
{
int myInt; int myChar;
std::tie(myInt, myChar) = std::get<1>(streamSender.myChildren);
return streamReceiver << "My int is " << myInt << " my char is " << ((char)myChar);
}
};
struct haveChildrenCharAndInt : public haveChildren<haveChildrenCharAndInt>
{
typedef std::tuple<char, int> innerContext;
haveChildrenCharAndInt() : haveChildren<haveChildrenCharAndInt>(10,'x') {}
};
int main(int argc, char* argv[])
{
cout << haveChildrenCharAndInt();
return 0;
}
那当然不会编译-但我希望你明白我想做什么。
可以通过像这样将类型作为模板参数传递来完成:
template<class DERIVED_TYPE,typename A,typename B>
struct haveChildren
{
const std::tuple<int, std::tuple<A, B> > myChildren;
haveChildren(int a, char b) : myChildren(5, std::tuple<A, B> { a, b }) {}
friend ostream& operator<< (ostream& streamReceiver, const haveChildren<DERIVED_TYPE,A,B>& streamSender)
{
int myInt; int myChar;
std::tie(myInt, myChar) = std::get<1>(streamSender.myChildren);
return streamReceiver << "My int is " << myInt << " my char is " << ((char)myChar);
}
};
struct haveChildrenCharAndInt : public haveChildren<haveChildrenCharAndInt,char,int>
{
typedef std::tuple<char, int> innerContext;
haveChildrenCharAndInt() : haveChildren<haveChildrenCharAndInt,char,int>(10,'x') {}
};
int main(int argc, char* argv[])
{
cout << haveChildrenCharAndInt();
return 0;
}
但是这个解决方案并不好,因为 class 作为成员变量应该具有的类型是 classes 并且它们是在之后创建的。
你们有没有人知道一种设计或技巧,可以让一个类型的成员变量在 class 从它继承之前没有定义 - 而不将类型作为模板参数传递?
您可以稍微改变您的设计并使其正常工作。
#include <tuple>
#include <iostream>
#include <ostream>
using namespace std;
// A helper class template to let you define the inner
// context of a derived type before the derived type is
// defined.
template <class DERIVED_TYPE> struct InnerContext;
template<class DERIVED_TYPE>
struct haveChildren
{
// Use the helper class template to get the inner context
// type of DERIVED_TYPE.
using DerivedInnerContext = typename InnerContext<DERIVED_TYPE>::type;
std::tuple<int, DerivedInnerContext> myChildren;
haveChildren(int a, char b) : myChildren(5, DerivedInnerContext{ a, b }) {}
friend ostream& operator<< (ostream& streamReceiver, const haveChildren& streamSender)
{
int myInt; int myChar;
std::tie(myInt, myChar) = std::get<1>(streamSender.myChildren);
return streamReceiver << "My int is " << myInt << " my char is " << ((char)myChar);
}
};
// Define the inner context of haveChildrenCharAndInt before
// haveChildrenCharAndInt is defined.
struct haveChildrenCharAndInt;
template <> struct InnerContext<haveChildrenCharAndInt>
{
using type = std::tuple<char, int>;
};
// haveChildrenCharAndInt is now simplified.
struct haveChildrenCharAndInt : public haveChildren<haveChildrenCharAndInt>
{
haveChildrenCharAndInt() : haveChildren<haveChildrenCharAndInt>(10,'x') {}
};
int main(int argc, char* argv[])
{
cout << haveChildrenCharAndInt();
return 0;
}
您可以将内部上下文作为类型特征进行传输:
template<typename Type>
struct inner_context;
并在基础 class 中使用它作为:
template<class Derived>
struct base {
using children_type = typename inner_context<Derived>::type;
const std::tuple<int, children_type> children;
base(int a, char b) : children(5, children_type{ a, b }) {}
};
然后每当你定义一个新类型时,你就声明了该类型的特化:
struct derived;
template<>
struct inner_context<derived> {
using type = std::tuple<char, int>;
};
最后是类型本身:
struct derived : public base<derived> {
derived() : base(10,'x') {}
};