这个问题适用于C ++ 03,而不是C ++ 11。
我有一个案例,我正在使用具有多重继承的CRTP,我很想知道是否有一种方法可以删除在下面指定B
类型时创建的冗余。
#include "boost/typeof/typeof.hpp"
#include "boost/units/detail/utility.hpp"
#include <iostream>
#include <string>
struct One{};
struct Two{};
template<typename T>
struct Type
{
static std::string name(void)
{
return boost::units::detail::demangle(typeid(T).name());
}
};
template<typename T1,
typename T2>
struct A
{
typedef A<T1, T2> Self;
A()
{
std::cout << Type<Self>::name() << std::endl;
}
};
template<typename T1,
typename T2,
typename T3>
struct B : public A<One, B<T1, T2, T3> >, // The B<T1, T2, T3> here is redundant
public A<Two, B<T1, T2, T3> >
{
typedef B<T1, T2, T3> Self;
B()
{
std::cout << Type<Self>::name() << std::endl;
}
};
int main(int argc, char* argv[])
{
B<int, int, int> t;
return 0;
}
上查看
当B
的模板参数数量增加,模板参数本身很复杂,B
从A
继承多次时,问题就会恶化。我想尽量减少B
模板参数的重复。具体来说,我正在寻找一种方法来访问typedef B<T1, T2, T3> Self
的继承列表中的B
,或者this
的一些等效编译时版本。
我不能:
B
B
创建一个typedef,因为我无法访问模板参数如下所示(其中没有一个不是有效代码,但显示我正在寻找的效果):
template<typename T1,
typename T2,
typename T3>
struct B : public A<One, Self>, // Cannot access the typedef yet
public A<Two, Self>
{
typedef B<T1, T2, T3> Self;
};
template<typename T1,
typename T2,
typename T3>
struct B : typedef B<T1, T2, T3> Self, // Invalid syntax
public A<One, Self>,
public A<Two, Self>
{
};
template<typename T1,
typename T2,
typename T3>
struct B : public A<One, B>, // I wish this would work
public A<Two, B>
{
};
template<typename T1,
typename T2,
typename T3>
struct B : public A<One, BOOST_TYPEOF(*this)>, // lol
public A<Two, BOOST_TYPEOF(*this)>
{
};
有没有办法访问this
的编译时版本?
答案 0 :(得分:0)
问题:
template<typename T1,
typename T2,
typename T3>
struct B : public A<One, B>, // I wish this would work
public A<Two, B>
{
};
是您的template <typename T1, typename T2> struct A
要求的
使用T2
类型进行实例化,而您希望可以执行此操作
用T2
模板来实例化它,即
template<typename, typename,typename> struct B
。
如果A
的定义在你自己的控制之下,那么也许 - 尽管可能不是 - 解决方案
是使A
的定义符合您的愿望:
#include "boost/typeof/typeof.hpp"
#include "boost/units/detail/utility.hpp"
#include <iostream>
#include <string>
struct One{};
struct Two{};
template<typename T>
struct Type
{
static std::string name(void)
{
return boost::units::detail::demangle(typeid(T).name());
}
};
template<typename T1,
template<typename, typename, typename> class T2
>
struct A
{
A()
{
std::cout << Type<A>::name() << std::endl;
}
};
template<typename T1,
typename T2,
typename T3>
struct B : public A<One, B >,
public A<Two, B >
{
B()
{
std::cout << Type<B>::name() << std::endl;
}
};
int main(int argc, char* argv[])
{
B<int, int, int> t;
return 0;
}
此程序打印:
A<One, B>
A<Two, B>
B<int, int, int>
此解决方案的价格限制了其中的类
A
可以为实例化模板的人提供CRTP基础,例如
B
,正好有三个typename
个参数。
也许你很幸运,这种限制不会阻碍任何其他限制
祝你有。但是如果你还需要A
来提供CRTP基础
对于实例化一些不具有三个模板的类的类
typename
参数,然后咬人。
前提是您需要A
提供CRTP的所有类
base是仅具有typename
个参数的模板的实例化,
并且最多只有N
个,那么你仍然可以拥有一个C ++ 03解决方案
同样的精神:
根据架构定义A
:
template<typename T1,
template<typename /*1*/,.... typename /*N*/> class T2
>
struct A { ... };
对于Y
作为CRTP基础的每个模板A
,您提供
准确N
参数,使用&#34;填充&#34;默认的参数
必要时void
。例如,如果N
== 3:
#include "boost/typeof/typeof.hpp"
#include "boost/units/detail/utility.hpp"
#include <iostream>
#include <string>
struct One{};
struct Two{};
template<typename T>
struct Type
{
static std::string name(void)
{
return boost::units::detail::demangle(typeid(T).name());
}
};
template<typename T1,
template<typename, typename, typename> class T2
>
struct A
{
A()
{
std::cout << Type<A>::name() << std::endl;
}
};
template<typename T1, typename T2 = void, typename T3 = void>
struct B : public A<One, B >,
public A<Two, B >
{
B()
{
std::cout << Type<B>::name() << std::endl;
}
};
template<typename T1, typename T2, typename T3 = void>
struct C : public A<One, C >,
public A<Two, C >
{
C()
{
std::cout << Type<C>::name() << std::endl;
}
};
template<typename T1, typename T2, typename T3>
struct D : public A<One, D >,
public A<Two, D >
{
D()
{
std::cout << Type<D>::name() << std::endl;
}
};
int main(int argc, char* argv[])
{
B<int> b;
C<int,int> c;
D<int,int,int> d;
return 0;
}
此程序打印:
A<One, B>
A<Two, B>
B<int, void, void>
A<One, C>
A<Two, C>
C<int, int, void>
A<One, D>
A<Two, D>
D<int, int, int>
是的,更通用的解决方案可以为您提供不同类型的&#34;冗余&#34;,in 那些多余的默认模板参数的形式。但是你 可能会觉得它不那么令人厌烦。
(gcc 5.1 / clang 3.6,C ++ 03)