Xeo*_*Xeo 25 c++ templates conditional-compilation compile-time
考虑以下类,将内部结构Y用作类型,例如.在模板中,稍后:
template<int I>
class X{
template<class T1>
struct Y{};
template<class T1, class T2>
struct Y{};
};
Run Code Online (Sandbox Code Playgroud)
现在,这个示例显然不会编译,错误是第二个X<I>::Y已经定义或者模板参数太多.
我想在没有(额外)部分特化的情况下解决这个问题,因为int I参数不是唯一的,并且它的位置可以在不同的部分特化中有所不同(我的实际结构看起来更像这样,上面只是为了简化问题),所以我想one class fits every I解决.
我的第一个想法显然是enable_if,但这似乎在我身上失败,例如.我仍然得到同样的错误:
// assuming C++11 support, else use boost
#include <type_traits>
template<int I>
class X{
template<class T1, class = std::enable_if<I==1>::type>
struct Y{};
template<class T1, class T2, class = std::enable_if<I==2>::type>
struct Y{};
};
Run Code Online (Sandbox Code Playgroud)
所以,既然enable_if失败了,我希望还有另一种方法来实现以下编译时检查:
template<int I>
class X{
__include_if(I == 1){
template<class T1>
struct Y{};
}
__include_if(I == 2){
template<class T1, class T2>
struct Y{};
}
};
Run Code Online (Sandbox Code Playgroud)
这只是为了节省我很多代码重复,但如果它在某种程度上可能会让我感到高兴.
编辑:可悲的是,我不能使用显而易见的:可变参数模板,因为我使用的是Visual Studio 2010,因此我只能使用支持的C++ 0x内容.:/
这里有两个问题:
enable_if 适用于部分专业化,而不是主要模板.正如您在聊天中所建议的,模板的链接列表可以模拟可变参数包.
template<int I>
class X{
template<class list, class = void>
struct Y;
template<class list>
struct Y< list, typename std::enable_if<I==1>::type > {
typedef typename list::type t1;
};
template<class list>
struct Y< list, typename std::enable_if<I==2>::type > {
typedef typename list::type t1;
typedef typename list::next::type t2;
};
};
Run Code Online (Sandbox Code Playgroud)
如果你最终得到next::next::next垃圾,很容易编写一个元函数,或者使用Boost MPL.
不同的arity模板可以相似地命名,但如果它们嵌套在SFINAE控制类型中,则仍然保持不同.
template<int I>
class X{
template<typename = void, typename = void>
struct Z;
template<typename v>
struct Z< v, typename std::enable_if<I==1>::type > {
template<class T1>
struct Y{};
};
template<typename v>
struct Z< v, typename std::enable_if<I==2>::type > {
template<class T1, class T2>
struct Y{};
};
};
X<1>::Z<>::Y< int > a;
X<2>::Z<>::Y< char, double > b;
Run Code Online (Sandbox Code Playgroud)