- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
这个问题是针对 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;
}
在 Coliru 上查看此内容
当 B
的模板参数数量增加时,问题会变得更糟增加,当模板参数本身很复杂,并且当B
继承自 A
更多次。我想尽量减少 B
的重复的模板参数。具体来说,我正在寻找一种方法来访问 typedef B<T1, T2, T3> Self
在 B
的继承列表中,或 this
的一些等效编译时版本.
我不能:
B
做一个typedef以上B
使用前向声明,因为我无权访问模板参数类似下面的内容(都不是无效代码,但显示了我正在寻找的效果):
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
的编译时版本? ?
最佳答案
问题在于:
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
参数,然后它咬。
前提是您需要的所有类(class) A
提供 CRTPbase 是只有 typename
的模板实例参数,最多有 N
其中,那么您仍然可以在同样的精神:
你定义A
根据架构:
template<typename T1,
template<typename /*1*/,.... typename /*N*/> class T2
>
struct A { ... };
并且对于每个模板Y
为此 A
是做一个CRTP基础,你提供正是 N
参数,使用默认为的“填充”参数 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>
是的,更通用的解决方案会让你陷入一种不同的“冗余”,在那些多余的默认模板参数的形式。但是你可能会觉得它不那么令人讨厌。
(gcc 5.1/clang 3.6, C++03)
关于c++ - 使用 CRTP 和多重继承消除冗余,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30940909/
我有下面提供的“示例代码”,我觉得这很多余,并且想请您与我一起解释是否有任何更少冗余的方法来处理以下代码。 public interface Bars { FOO1 FOO1 = (FOO1)
我们刚刚测试了一个由 2 个服务器组成的 AppFabric 集群,我们在其中删除了“领导”服务器。第二个服务器对它的任何请求超时并出现错误: Microsoft.ApplicationServer.
我正在设计一个关系数据库 - 底层是 MySQL - DBDesigner 4 . 我有 3 个表:module、page 和 lang。每个模块属于一个页面,每个页面都有特定的语言: 外键 pag
我的 Fraction 程序运行流畅,但 NetBeans IDE 告诉我以下 if 是多余的: public boolean equals(Object other) { Fraction bo
下面的代码显然是多余的,但根据我的经验,我经常使用这种模式。有没有更好的方法在 python 中执行此操作? if re.search("at (\d{1,2}):\d{2}", p): a=
我有一个用具体示例说明的一般性问题。当所有组件对象都已测试时,您建议对复合对象进行多少测试? 作为具体示例,请考虑下面的 NullTerminatedStringReader。它从字节缓冲区中读取一个
if ( a > b) { return true; } return false; 对于上面的代码,Netbeans 给出了 “Redundant if statement” 警告并建议将其更改
当我添加一些约束时,例如: create table Test( IDTest int primary key, Credit int not null constraint Credit
此代码适用于 Microchip 的 PIC32MX 微处理器。他们的编译器本质上是 GCC 3.4。 我倾向于使用 GCC 的 __packed__ attribute将位域打包到一个 union
已关闭。这个问题是 not reproducible or was caused by typos 。目前不接受答案。 这个问题是由拼写错误或无法再重现的问题引起的。虽然类似的问题可能是 on-top
我正在为我的应用程序使用apns通知,为此,我将apns设备 token 存储在我的sql数据库中。 问题在于,每次用户删除或安装该应用程序时,它都会生成一个新的设备 token ,并将其存储在数据库
Action Keyname Type Unique Packed Column Cardinality Collation Null Comment Edit Dro
我正在开发一个使用 ARM Cortex-M0 处理器的项目。在这个项目中,我需要提供计时器支持(CMSDK (SSE-200)计时器)。 因此,在 vector 表中,在 TIMER0_IRQn 表
有没有写的理由 corsFilter.setAllowedOrigins(new HashSet(Arrays.asList("*"))); 其中allowedOrigins在ReSTLet框架中的定
我正在创建一个包含 4 个链接的 HTML/CSS 页面, Home.html Details.html ContactMe.html AboutUs.html 我想在所有关联的 HTML 页面中将其
我试图理解并使用其他人编写的代码,但由于我对 typedef 经验不多。 , 我有时会感到困惑。 有两个不同的头文件,一个继承另一个,并且在两个文件上声明相同的typedef。 为什么会出现冗余,如何
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我有一个用于改造的 POJO 类。 public class AppData(){ String a; String b; String c;
我想知道: 编写这段代码: DataRow[] g = new DataRow[1] ; var t=new StringBuilder().AppendFormat("{0}", g[0]["a
只是一个性能问题...... 假设我有 5 个类,每个类都引用了 System.Data 和一个自己开发的库。这 5 个类是类库的一部分,最终将被构建并发布到一些 Web 应用程序作为引用。 通过将引
我是一名优秀的程序员,十分优秀!