- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我已经定义了一个作为整数的类型。我想为我的类型定义 std::common_type 的特化。然而,这个特化应该能够给出 bounded_integer (我的类)的 common_type 与任意数量的其他 bounded_integer 或内置整数类型的参数的组合。我希望以下代码全部有效:
std::common_type<bounded_integer<1, 10>>::type
std::common_type<bounded_integer<1, 10>, int>::type
std::common_type<int, long, bounded_integer<1, 10>>::type
std::common_type<int, int, long, short, long long, short, bounded_integer<1, 10>, int, short, short, short, ..., short, bounded_integer<1, 10>>::type
我第一次尝试解决这个问题是使用 enable_if。然而,我意识到这不允许我与 common_type 的库定义区分开来,因为我所拥有的本质上是
#include <type_traits>
class C {};
template<typename T, typename... Ts>
class contains_c {
public:
static constexpr bool value = contains_c<T>::value or contains_c<Ts...>::value;
};
template<typename T>
class contains_c<T> {
public:
static constexpr bool value = std::is_same<T, C>::value;
};
namespace std {
template<typename... Args, typename std::enable_if<contains_c<Args...>::value>::type>
class common_type<Args...> {
public:
using type = C;
};
} // namespace std
int main() {
}
“部分特化”实际上只是“任何参数”,它并不比我们拥有的更专业。
所以看起来唯一的解决方案是要求我的用户执行以下操作之一:
3 看起来像这样:
// all_bounded_integer_or_integral and all_are_integral defined elsewhere with obvious definitions
template<intmax_t minimum, intmax_t maximum, typename... Ts, typename = type std::enable_if<all_bounded_integer_or_integral<Ts...>::value>::type>
class common_type<bounded_integer<minimum, maximum>, Ts...> {
};
template<typename T1, intmax_t minimum, intmax_t maximum, typename... Ts, typename = typename std::enable_if<all_are_integral<T1>::value>::type, typename = typename std::enable_if<all_bounded_integer_or_builtin<Ts...>::value>::type>
class common_type<T1, bounded_integer<minimum, maximum>, Ts...> {
};
template<typename T1, typename T2, intmax_t minimum, intmax_t maximum, typename... Ts, typename = typename std::enable_if<all_are_integral<T1, T2>::value>::type, typename = typename std::enable_if<all_bounded_integer_or_builtin<Ts...>::value>::type>
class common_type<T1, T2, bounded_integer<minimum, maximum>, Ts...> {
};
// etc.
对于我无法更改其原始定义的类,是否有更好的方法来实现此目的(当所有类型都满足一个条件并且任何类型都满足另一个条件时的模板特化)?
编辑:
根据答案,我的问题还不够清楚。
首先,预期行为:
如果有人调用 std::common_type 并且所有类型都是 bounded_integer 的实例或内置数字类型,我希望结果是一个 bounded_integer,它具有所有可能的最小值中的最小值和最大值所有可能的最大值。
问题:
当有人对任意数量的 bounded_integer 调用 std::common_type 时,我有一个可行的解决方案。但是,如果我只特化两个参数的版本,那么我会遇到以下问题:
std::common_type<int, unsigned, bounded_integer<0, std::numeric_limits<unsigned>::max() + 1>
应该给我
bounded_integer<std::numeric_limits<int>::min(), std::numeric_limits<unsigned>::max() + 1>
然而,事实并非如此。它首先将 common_type 应用于 int
和 unsigned
,它遵循标准积分提升规则,给出 unsigned
.然后它返回 common_type
的结果与 unsigned
和我的 bounded_integer
, 给予
bounded_integer<0, std::numeric_limits<unsigned>::max() + 1>
所以通过添加 unsigned
到参数包的中间,即使它对结果类型绝对没有影响(它的范围完全包含在所有其他类型的范围内),它仍然会影响结果。我能想到的防止这种情况的唯一方法是专门化 std::common_type
对于任意数量的内置整数,后跟 bounded_integer
, 后跟任意数量的内置整数或 bounded_integer
.
我的问题是:我怎样才能做到这一点而不必通过手动写出任意数量的参数后跟一个 bounded_integer
来近似它?后跟一个参数包,或者这是不可能的?
编辑 2:
common_type 会给出错误值的原因可以用这个遵循标准的推理来解释(引用自 N3337)
common_type
的 int
和 unsigned
是unsigned
.例如:http://ideone.com/9IxKIW .标准语可在§ 20.9.7.6/3 中找到,其中 common_type
两个值的是
typedef decltype(true ? declval<T>() : declval<U>()) type;
在 § 5.16/6 中,它说
The second and third operands have arithmetic or enumeration type; the usual arithmetic conversions are performed to bring them to a common type, and the result is of that type.
通常的算术转换在 § 5/9 中定义为
Otherwise, if the operand that has unsigned integer type has rank greater than or equal to the rank of the type of the other operand, the operand with signed integer type shall be converted to the type of the operand with unsigned integer type.
最佳答案
std::common_type
将其自身的双参数特化外推到 n 参数情况。您只需要专门化两个参数的情况。
template< typename other, int low, int high >
struct common_type< other, ::my::ranged_integer< low, high > > {
using type = other;
};
template< typename other, int low, int high >
struct common_type< ::my::ranged_integer< low, high >, other > {
using type = other;
};
template< int low, int high >
struct common_type< ::my::ranged_integer< low, high >,
::my::ranged_integer< low, high > > {
using type = ::my::ranged_integer< low, high >;
};
这使得不同范围整数之间的 common_type
未定义。我想您可以使用 min
和 max
来完成。
如果你的类支持继承,你也可以制作一个is_ranged_integer
trait。
不要忘记将您的库放在命名空间中。
关于c++ - 出现在可变模板参数包的任何位置的类型的类模板的部分特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18679093/
为什么禁用类型像 type t = A of int | B of string * mutable int 虽然允许此类类型: type t = A of int | B of string * i
我正在寻找一种类似结构的数据结构,我可以从中创建多个实例并具有某种类型提示而不是不可变的。 所以我有这样的东西: class ConnectionConfig(NamedTuple): nam
我需要转到引用的结构: class SearchKnot { var isWord : Bool = false var text : String = "" var to
如sec 10.4.3中所述 当控制进入执行时,执行以下步骤 功能对象F(调用者)中包含的功能代码的上下文 提供thisArg,而调用方提供argumentsList: 如
i make a game that start display Activity indicator And activity indicator bottom display UiLable wi
编辑:我在这里不断获得支持。只是为了记录,我认为这不再重要。自从我发布它以来我就不再需要它了。 我想在 Scala 中执行以下操作... def save(srcPath: String, destP
使用可变对象作为 Hashmap 键是一种不好的做法吗?当您尝试使用已修改足以更改其哈希码的键从 HashMap 中检索值时,会发生什么? 例如,给定 class Key { int a; /
如果您在Kotlin中访问List类型的Java值,则将获得(Mutable)List!类型。 例如。: Java代码: public class Example { public stati
我编写了 str 类(内置)的以下扩展,以便执行以下操作:假设我有字符串 "Ciao" ,通过做"Ciao" - "a"我想要的结果是字符串 "Cio" 。这是执行此操作的代码,并且运行良好: cla
使用可变对象作为 Hashmap 键是一种不好的做法吗?当您尝试使用已修改足以更改其哈希码的键从 HashMap 中检索值时,会发生什么? 例如,给定 class Key { int a; /
我正在为我的公司设计一个数据库来管理商业贷款。每笔贷款都可以有担保人,可以是个人或公司,在借款业务失败时作为财务支持。 我有 3 个表:Loan、Person 和 Company,它们存储明显的信息。
我使用二进制序列化从 C# 类中保存 F# 记录。一切正常: F#: type GameState = { LevelStatus : LevelStatus
import javax.swing.JOptionPane; public class HW { public static void main(String[] args) { Strin
使用 flatbuffer mutable 有多少性能损失? 是否“正确”使用 FlatBuffers 来拥有一个应该可编辑的对象/结构(即游戏状态) 在我的示例中,我现在有以下类: class Ga
std::function create_function (args...) { int x = initial_value (args...); return [x] () mut
我需要在 for 循环中找到用户输入的字符。我通常会这样做 如果(句子[i] == 'e') 但是因为在这里,'e' 将是一个单字母字符变量,我不知道如何获取要比较的值。我不能只输入 if (sent
我有一个这样的算法: let seed: Foo = ... let mut stack: Vec = Vec::new(); stack.push(&seed); while let Some(ne
这个问题可能看起来非常基础,但我很难弄清楚如何做。我有一个整数,我需要使用 for 循环来循环整数次。 首先,我尝试了—— fn main() { let number = 10; // An
如果我有以下结构: struct MyStruct { tuple: (i32, i32) }; 以及以下函数: // This will not compile fn function(&mut s
我希望在每个 session 的基础上指定列的默认值。下面的脚本不起作用,但描述了我想如何使用它。我目前使用的是 MySQL 5.5.28,但如果需要可以升级。 CREATE TABLE my_tbl
我是一名优秀的程序员,十分优秀!