- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想定义一个函数template<typename T> T constCast(const ScriptVar_t& s);
.取决于T
,我想有不同的定义。 (ScriptVar_t
是一个类,但细节在这里并不重要。)
关于 T
的条件不像特定类型那么简单,它们都是稍微复杂一些的静态 bool 表达式。 IE。我有一个表达式列表 ext1
.. extN
对于每个函数,我都有该函数的定义。我希望按顺序检查它们,并且应该使用第一个匹配表达式的定义。如果它们都失败了,我想得到一个编译器错误。
现在,我只有 2 个定义,我的代码如下所示(这是一个完整的测试用例,已标记相关代码):
#include <boost/type_traits.hpp>
enum {
SVT_INT,
SVT_FLOAT,
SVT_BASEOBJ,
SVT_CUSTOMVAR
};
struct BaseObject {};
struct CustomVar {};
template<typename T> struct GetType;
template<> struct GetType<int> { static const int value = SVT_INT; };
template<> struct GetType<float> { static const int value = SVT_FLOAT; };
template<> struct GetType<BaseObject> { static const int value = SVT_BASEOBJ; };
template<bool> struct GetType_BaseCustomVar;
template<> struct GetType_BaseCustomVar<true> {
struct Type { static const int value = SVT_CUSTOMVAR; };
};
template<typename T> struct GetType : GetType_BaseCustomVar<boost::is_base_of<CustomVar,T>::value>::Type {};
struct ScriptVar_t;
template<typename T> T CastScriptVarConst(const ScriptVar_t& s);
struct ScriptVar_t {
operator int() const { return 0; }
operator float() const { return 0.0f; }
operator BaseObject() const { return BaseObject(); }
template<typename T> T* as() const { return NULL; }
template <typename T> T castConst() const { return CastScriptVarConst<T>(*this); }
};
// *** relevant code starts here
template<typename T> T CastScriptVarConst(const ScriptVar_t& s);
template<bool> struct CastScriptVar1;
template<typename T> struct CastScriptVar1_IsSimpleType {
static const bool value = GetType<T>::value < SVT_BASEOBJ;
};
template<> struct CastScriptVar1<true> {
template<typename T> static T castConst(const ScriptVar_t& s, const T& /*dummy*/) { return (T) s; }
};
template<bool> struct CastScriptVar2;
template<typename T> struct CastScriptVar2_IsCustomVar {
static const bool value = boost::is_base_of<CustomVar,T>::value;
};
template<> struct CastScriptVar2<true> {
template<typename T> static T castConst(const ScriptVar_t& s, const T& /*dummy*/) { return *s.as<T>(); }
};
template<> struct CastScriptVar1<false> {
template<typename T> static T castConst(const ScriptVar_t& s, const T& /*dummy*/) {
return CastScriptVar2<CastScriptVar2_IsCustomVar<T>::value>::castConst(s, T());
}
};
template<typename T> T CastScriptVarConst(const ScriptVar_t& s) {
return CastScriptVar1<CastScriptVar1_IsSimpleType<T>::value>::castConst(s, T());
}
int main() {
ScriptVar_t v;
v.castConst<int>();
v.castConst<CustomVar>();
}
经过几次尝试,我想出了这个办法,直到它成功为止。
(从代码中可以看出,这两个表达式是GetType<T>::value < SVT_BASEOBJ
和boost::is_base_of<CustomVar,T>::value
,如果都为false,编译器应该会报错。但这只是我的问题的一个例子。)
我想知道这段代码是否有更简洁的解决方案。
作为引用,我正在玩它here .现在,我又有了一个与此处所有其他解决方案略有不同的解决方案。
最佳答案
所以如果我没理解错的话,你有两种施法方法。如果GetType<T>::value < SVT_BASEOBJ
那么你只想使用普通类型转换:(T) s;
另一方面,如果GetType<T>::value < SVT_BASEOBJ
是 false 那么你要确保 CustomVar
是 T
类型的基类(即 T
派生自 CustomVar
)。然后你想在那个对象上使用一个成员函数:*s.as<T>()
否则会出现编译错误。
这是使用重载和 std::enable_if
实现的一种方法:
template<typename T>
typename std::enable_if<GetType<T>::value < SVT_BASEOBJ,T>::type
CastScriptVarConst(const ScriptVar_t& s) {
return (T) s;
}
template<typename T>
typename std::enable_if<!(GetType<T>::value < SVT_BASEOBJ)
&& std::is_base_of<CustomVar,T>::value,T>::type
CastScriptVarConst(const ScriptVar_t& s) {
return *s.as<T>();
}
enable_if
利用 C++ 中的 SFINAE 规则,因此如果条件失败,唯一的后果是该函数不会添加到该调用的可行重载集中。自 enable_if
条件是相互排斥的,至多一个函数对于任何给定的调用都是可行的,因此永远不会有歧义。如果这两个条件都不成立,那么您将收到一个编译错误,提示找不到匹配的函数。
#include <type_traits>
#include <iostream>
enum {
SVT_INT,
SVT_FLOAT,
SVT_BASEOBJ,
SVT_CUSTOMVAR
};
struct BaseObject {};
struct CustomVar {};
template<typename T> struct GetType;
template<> struct GetType<int> { static const int value = SVT_INT; };
template<> struct GetType<float> { static const int value = SVT_FLOAT; };
template<> struct GetType<BaseObject> { static const int value = SVT_BASEOBJ; };
template<bool> struct GetType_BaseCustomVar;
template<> struct GetType_BaseCustomVar<true> {
struct Type { static const int value = SVT_CUSTOMVAR; };
};
template<typename T> struct GetType : GetType_BaseCustomVar<std::is_base_of<CustomVar,T>::value>::Type {};
struct ScriptVar_t {
operator int() const { return 0; }
operator float() const { return 0.0f; }
operator BaseObject() const { return BaseObject(); }
template<typename T> T* as() const { return NULL; }
template <typename T> T castConst() const;
};
template<typename T>
typename std::enable_if<GetType<T>::value < SVT_BASEOBJ,T>::type
CastScriptVarConst(const ScriptVar_t& s) {
std::cout << "value < SVT_BASEOBJT\n";
return (T) s;
}
template<typename T>
typename std::enable_if<!(GetType<T>::value < SVT_BASEOBJ)
&& std::is_base_of<CustomVar,T>::value,T>::type
CastScriptVarConst(const ScriptVar_t& s) {
std::cout << "CustomVar\n";
return *s.as<T>();
}
template <typename T>
T ScriptVar_t::castConst() const {
return CastScriptVarConst<T>(*this);
}
int main() {
ScriptVar_t v;
v.castConst<int>();
v.castConst<CustomVar>();
}
关于C++ 和类型特征 : simplest way of defining a list of possible definitions,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9570985/
我有一个包含需要排序的不同项目的列表。但还有一个额外的问题:某些元素只允许出现在列表中的特定位置。 示例(请查看 http://jsfiddle.net/pYL32/2/ ):有一个包含元素 foo、
关于https://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained据解释,guava(以及后来的 java 8
我有一个名为 say CalculationOutcome 的类(class)和 FileHashOutcome .他们的构造函数有 (ActualResult, Throwable)参数,并在 Co
我正在使用pycharm,我的代码在分屏上。当我运行调试时,会弹出调试/运行窗口,它非常分散注意力并且限制了我在调试时可以查看的代码量......但我想保持它,因为我来回走动;另外,我想要调试变量的完
这个问题已经有答案了: 已关闭11 年前。 Possible Duplicate: javascript object, access variable property name? 我确信这是可以完
if (typeof Object.create !== 'function') { Object.create = function (o) { function F() {
在将实体存储在 redis 中作为序列化二进制 blob 的应用程序中工作。我有多个客户端处理同一个数据集,我希望使用乐观并发。 我的要求是: 在一次往返中读取特定键的序列化实体 将修改后的实体写回r
这个问题是指 C/x86 上使用的 IEEE 标准浮点数。 是否可以将任何数字(即不包括 NaN 之类的特殊值)浮点数或 double 数表示为十进制字符串,以便将该字符串转换回浮点数/ double
我的团队目前正在与 Lua 合作,创建一个 android 游戏。我们遇到的一件事是表面上无法创建重载构造函数。 我习惯于使用默认值设置一个对象,然后在需要时使其过载。 前任: apples() {
如何在 Scene Kit 中使用 SCNCamera 获得像鱼眼镜头那样的失真? 类似于这种图像的“鞠躬”: //正如 Rickster 指出的那样,这种失真被称为“桶形失真”。 从文档中,这是让我
我想问是否有一种方法可以多次评估 javascript 术语,而不需要一遍又一遍地解析一个术语。 说,您想要评估 var1/var2+Math.sqrt(var3) 每秒 20 次。 使用时这可能会出
我想知道在技术上是否可以在 java applet 中创建代理。 那么是否可以通过这个 java applet 代理路由所有进一步的浏览器请求? 例如,如果用户要浏览 google.com,默认行为是
我有以下代码,我想返回一个 bool 值或一个元组。 (函数 isvariable 和 dont_care 都返回 bool 值,仅供引用) let match_element (a, b) = if
这个问题困扰我很久了。我想要一个二叉树(或类似的嵌套结构)上的迭代器,它高效、简单且Pythonic。例如,对于这样的用法: for value in values(root): do_som
目前我有以下 MySQL 查询: SELECT COUNT(*) AS `count`, `v`.`value` FROM `client_entity_int` AS `v` INN
我正在使用 Angular 开发应用程序,客户端是 100% JS。我即将替换使用 ExtJS 制作的旧应用程序,但我不会更改服务器端。只有客户端从头开始重新编码。 我想在任何地方和任何机器上处理这个
有没有办法在运行时检索实例的声明类?例如: public class Caller { private JFrame frame = new JFrame("Test"); priva
我目前正在请求 MySQL 数据库使用 PDO 计算一些计数和总和。这个过程可能需要一段时间,如果用户突然想浏览另一个页面,他可能会停留在浏览器前面。 我试图弄清楚是否可以使用 PDO 启动 MySQ
想知道它是不是这样工作的: $result .= mysqli_query($query1); $result .= mysqli_query($query2); $result 会是查询 1 和 2
所以我有这样的挑战: body 背景上的图像,背景大小,覆盖以适合整个屏幕。在背景图像上是一些元素(建筑物)。所以我想将鼠标悬停在建筑物上,他们会更改颜色或添加阴影等。问题在于屏幕调整大小,当我调整屏
我是一名优秀的程序员,十分优秀!