- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
作为一个玩具示例,我有一个简单地将向量或矩阵包装在对象中并包含其创建时间的时间戳的类。我正在尝试重载 subsref
以便
()
引用的工作方式与标准向量和矩阵类型完全相同{}
引用在中的工作方式与 ()
引用相同(换句话说,与单元格无关).
引用允许我访问对象的私有(private) 属性和技术上不属于属性的其他字段。 代码:
classdef TimeStampValue
properties (Access = private)
time;
values;
end
methods
%% Constructor
function x = TimeStampValue(values)
x.time = now();
x.values = values;
end
%% Subscripted reference
function x = subsref(B, S)
switch S.type
case '()'
v = builtin('subsref', B.values, S);
x = TimeStampValue(v);
case '{}'
S.type = '()';
v = builtin('subsref', B.values, S);
x = TimeStampValue(v);
case '.'
switch S.subs
case 'time'
x = B.time;
case 'values'
x = B.values;
case 'datestr'
x = datestr(B.time);
end
end
end
function disp(x)
fprintf('\t%d\n', x.time)
disp(x.values)
end
end
end
但是大括号 {}
引用不起作用。我运行这段代码
clear all
x = TimeStampValue(magic(3));
x{1:2}
我得到这个错误:
Error using TimeStampValue/subsref
Too many output arguments.
Error in main (line 3)
x{1:2}
MException.last
给我这个信息:
identifier: 'MATLAB:maxlhs'
message: 'Too many output arguments.'
cause: {0x1 cell}
stack: [1x1 struct]
这没有帮助,因为异常堆栈中唯一的东西是包含我在上面运行的三行代码的文件。
我在 subsref
中 switch 语句的第一行放置了一个断点,但 MATLAB 从未到达它。
这是怎么回事? ()
和 .
引用都按您预期的方式工作,那么为什么 {}
引用不起作用?
最佳答案
当重载花括号 {}
以返回与平时不同数量的输出参数时,还需要重载 numel
以返回预期的数字 (1,在这种情况下)。 更新:自 R2015b 起,创建了新函数 numArgumentsFromSubscript
以重载,而不是 numel
。问题仍然存在,但是应该重载此函数而不是 numel
,正如我在下面的原始答案中所描述的那样。另请参阅页面 "Modify nargout and nargin for Indexing Methods" 。摘录:
When a class overloads
numArgumentsFromSubscript
, MATLAB calls this method instead ofnumel
to compute the number of arguments expected forsubsref
nargout
andsubsasgn
nargin
.If classes do not overload
numArgumentsFromSubscript
, MATLAB callsnumel
to compute the values ofnargout
ornargin
.
下面是对潜在问题的更多解释(需要指定输出参数的数量)。
原始答案(使用 numArgumentsFromSubscript
而不是 R2015b+ 的 numel
)
为了在使用花括号进行索引时处理逗号分隔的输出参数列表的可能性,MATLAB 调用 numel
以根据输入索引的大小确定输出参数的数量(根据 this MathWorks answer ) .如果重载 subsref
定义中的输出参数数量与 numel
提供的数量不一致(即小于),则会出现“输出参数过多”错误.正如 MathWorks 所述:
Therefore, to allow curly brace indexing into your object while returning a number of arguments INCONSISTENT with the size of the input, you will need to overload the NUMEL function inside your class directory.
由于 x{1:2}
通常提供两个输出 (X{1},X{2}
),定义 function x = subsref( B, S)
与此输入不兼容。解决方案是在类中包含一个简单的 numel
方法来重载内置函数,如下所示:
function n = numel(varargin)
n = 1;
end
现在 {}
索引按预期工作,模仿 ()
:
>> clear all % needed to reset the class definition
>> x = TimeStampValue(magic(3));
>> x(1:2)
ans =
7.355996e+05
8 3
>> x{1:2}
ans =
7.355996e+05
8 3
但是,以这种方式重载花括号是 apparently 一种“我们 [MathWorks] 不希望客户编写的特定类型的代码”。 MathWorks 建议:
If you are designing your class to output only one argument, it is not recommended that you use curly brace indexing that requires you to overload NUMEL. Instead, it is recommended you use smooth brace () indexing.
更新:有趣的是,R2015b release notes state:
Before MATLAB release R2015b, MATLAB incorrectly computed the number of arguments expected for outputs from
subsref
and inputs tosubsasgn
for some indexing expressions that return or assign to a comma-separated list.With release R2015b, MATLAB correctly computes the values of
nargout
andnargin
according to the number of arguments required by the indexing expression.
所以也许现在这个问题已经解决了?
想到的另一种解决方案是将 function x = subsref(B, S)
更改为 function varargout = subsref(B, S)
并添加 varargout=cell(1,numel(B)); varargout{1} = x;
.正如 Amro 在评论中指出的那样,预先分配单元格对于避免有关未分配参数的错误是必要的。
关于matlab - 为什么当我重载 subsref(下标引用)时 MATLAB 会抛出 "too many output arguments"错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20863050/
假设我有一个类,我在其中重载了运算符 == : Class A { ... public: bool operator== (const A &rhs) const; ... };
我知道你不应该使用 std::find(some_map.begin(), some_map.end()) 或 std::lower_bound,因为它会采用线性时间而不是 some_map.lowe
我正在尝试在 Haskell 中定义 Vector3 数据类型,并允许在其上使用 (+) 运算符。我尝试了以下方法: data Vector3 = Vector3 Double Double Doub
我已经为我的类图将运算符重载为“-”。它的用途并不完全直观(糟糕的编码 - 我知道)但是如果我做 graph3 = graph2-graph1 那么图 3 是应该只接收图 2 和图 1 中的那些顶点。
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: Operator overloading 我想重载 以按字母顺序排列字符串,但我不确定该怎么做。 如何再次
下面的代码给我一个编译错误。谁能告诉我为什么? class mytype { public: int value; mytype(int a) { value = a;
这有什么问题吗? class Vec2 attr_accessor :x, :y # ... def += (v) @x += v.x @y += v.y retu
是否可以重载 [] 运算符两次?允许这样的事情:function[3][3](就像在二维数组中一样)。 如果可能的话,我想看看一些示例代码。 最佳答案 您可以重载 operator[] 以返回一个对象
我的团队目前正在与 Lua 合作,创建一个 android 游戏。我们遇到的一件事是表面上无法创建重载构造函数。 我习惯于使用默认值设置一个对象,然后在需要时使其过载。 前任: apples() {
我有一个网页,在某个时候显示一个导航栏,它只不过是一个 a 元素的列表 (ul)。所述 a 元素的大多数样式规则都是通用的。唯一应该改变的部分是要显示的图像,可以从列表中每个 li 元素的 id 标签
我对使用/重载“范围步长”运算符(.. ..)很感兴趣,但我终其一生都无法了解如何使用它。 在文档中它说 // Usage: start .. step .. finish 但是在 F# shell
Java 11(可能无关紧要): public static String toString(Object obj) { return ReflectionToStringBuilder.to
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我无法理解以下代码(针对行号进行注释) class Base { void m1(Object o) { } void m2(String o) { } } publi
我有以下代码片段: #include using namespace std; struct Integer{ int x; Integer(const int val) : x(v
class myclass{ //definitions here }; myclass e; int myarray[10]; /* Do something... */ e = myarray;
为什么不能将下标运算符(operator [])作为 friend 函数重载? 最佳答案 正如Bjarne Stroustrup在D&E book中所说: However, even in the o
我有以下代码片段: #include using namespace std; struct Integer{ int x; Integer(const int val) : x(v
因此,我有一个问题是我最近尝试重载 namespace Eng { /** * A structure to represent pixels */ typedef
如何重载onResume()以正确的方式工作?我想从 activity 返回到 MainActivity ,我希望在其中具有与应用程序启动后相同的状态。我想使用 recreate() 但它循环了或者类
我是一名优秀的程序员,十分优秀!