当花括号过载时{}
要返回与平常不同数量的输出参数,还需要重载numel
返回预期的数字(在本例中为 1)。UPDATE: As of R2015b,新函数numArgumentsFromSubscript https://www.mathworks.com/help/matlab/ref/numargumentsfromsubscript.html被创建为重载而不是numel
。问题仍然相同,但应该重载该函数而不是numel
正如我在下面的原始答案中所描述的。另请参阅页面“修改索引方法的 nargout 和 nargin” https://www.mathworks.com/help/matlab/matlab_oop/overloading-numel-subsref-and-subsasgn.html。摘抄:
当一个类超载时numArgumentsFromSubscript
,MATLAB 调用此方法而不是numel
计算预期的参数数量subsref
nargout
and subsasgn
nargin
.
如果类没有超载numArgumentsFromSubscript
, MATLAB 调用numel
计算的值nargout
or nargin
.
下面是对根本问题的更多解释(需要指定输出参数的数量)。
原始答案(使用numArgumentsFromSubscript
代替numel
对于 R2015b+)
为了处理使用大括号索引时逗号分隔的输出参数列表的可能性,MATLAB 调用numel
根据输入索引的大小确定输出参数的数量(根据这个 MathWorks 答案 http://www.mathworks.com/matlabcentral/answers/101955#answer_111302)。如果重载定义中的输出参数数量subsref
与提供的数字不一致(即小于)numel
,您会收到“输出参数太多”错误。正如 MathWorks 所说:
因此,为了允许在对象中使用大括号索引,同时返回与输入大小不一致的参数数量,您需要在类目录中重载 NUMEL 函数。
Since x{1:2}
通常提供两个输出(X{1},X{2}
), 定义function x = subsref(B, S)
与此输入不兼容。解决方案是在类中包含一个简单的numel
方法重载内置函数,如下:
function n = numel(varargin)
n = 1;
end
Now the {}
索引按预期工作,模仿()
:
>> 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
然而,以这种方式重载花括号是显然 http://www.mathworks.com/matlabcentral/answers/101955#answer_111302“我们 [MathWorks] 不希望客户编写的特定类型的代码”。 MathWorks 建议:
如果您将类设计为仅输出一个参数,则不建议您使用需要重载 NUMEL 的大括号索引。相反,建议您使用平滑大括号 () 索引。
UPDATE:有趣的是,R2015b 发行说明状态 https://www.mathworks.com/help/matlab/release-notes.html#bu0biit-3:
在 MATLAB 发布 R2015b 之前,MATLAB 错误地计算了输出的预期参数数量subsref
并输入subsasgn
对于某些返回或分配给逗号分隔列表的索引表达式。
在 R2015b 版本中,MATLAB 可以正确计算nargout
and nargin
根据索引表达式所需的参数数量。
那么也许这个问题现在已经解决了?
我想到的另一种解决方案是改变function x = subsref(B, S)
to function varargout = subsref(B, S)
并添加varargout=cell(1,numel(B)); varargout{1} = x;
。正如 Amro 在评论中指出的那样,必须预先分配单元格,以避免出现有关未分配参数的错误。