考虑您想要使用包含以下方法签名来模拟接口:Mockito
public void doThis(Object o);
public void doThis(Object... o)
Run Code Online (Sandbox Code Playgroud)
我需要验证(doThis(Object o)而不是其他方法)是否已被调用一次。
首先,我认为下面的行可以解决问题:
verify(mock, times(1)).doThis(anyObject());
Run Code Online (Sandbox Code Playgroud)
doThis然而,这似乎在 Windows 上有效,但在 Linux 上却不起作用,因为在这种环境中,需要调用其他方法。
这是因为anyObject()参数似乎与两个方法签名都匹配,并且以或多或少不可预测的方式选择了一个方法签名。
如何强制Mockito 始终选择doThis(Object o)进行验证?
我有几个与 C++ 中的重载解析相关的问题。考虑这个例子:
extern "C" int printf (const char*, ...);
struct X {};
template <typename T>
struct A
{
A() = default;
template <typename U>
A(A<U>&&)
{printf("%s \n", __PRETTY_FUNCTION__);}
};
template <typename T>
struct B : A<T>
{
B() = default;
template <typename U>
operator A<U>()
{printf("%s \n", __PRETTY_FUNCTION__); return {};}
};
int main ()
{
A<X> a1 (B<int>{});
}
Run Code Online (Sandbox Code Playgroud)
如果我用 编译它g++ -std=c++11 a.cpp,A的构造函数将被调用:
A<T>::A(A<U>&&) [with U = int; T = X]
Run Code Online (Sandbox Code Playgroud)
如果我用 编译程序g++ -std=c++17 …
如果我们有:
void foo(int) {}
void foo(const int&) {}
Run Code Online (Sandbox Code Playgroud)
我们不能这样调用foo:
foo(3);
Run Code Online (Sandbox Code Playgroud)
因为调用是模棱两可的:
Run Code Online (Sandbox Code Playgroud)error: call of overloaded 'foo(int)' is ambiguous 40 | foo(3); | ^ note: candidate: 'void foo(int)' 36 | void foo(int) {} | ^~~ note: candidate: 'void foo(const int&)' 37 | void foo(const int&) {} | ^~~
我们可以做的是明确提供正确的重载,例如通过函数指针:
auto (*ptr)(const int&) -> void = foo;
ptr(3); // calls the "const int&" overload, obviously
Run Code Online (Sandbox Code Playgroud)
然而,这种方式违背了方便重载的目的。问题是 - 我可以以某种方式以更......优雅的方式消除呼叫的歧义吗?道路?是否有过哪里会需要提供案件都过载,为T和const T& …
我想<<为任何人写一个泛型,range最后我得到了这个:
std::ostream& operator << (std::ostream& out, std::ranges::range auto&& range) {
using namespace std::ranges;
if (empty(range)) {
return out << "[]";
}
auto current = begin(range);
out << '[' << *current;
while(++current != end(range)) {
out << ',' << *current;
}
return out << ']';
}
Run Code Online (Sandbox Code Playgroud)
像这样测试:
int main() {
std::vector<int> ints = {1, 2, 3, 4};
std::cout << ints << '\n';
}
Run Code Online (Sandbox Code Playgroud)
它完美运行并输出:
Run Code Online (Sandbox Code Playgroud)[1,2,3,4]
但是,当测试时:
int main() {
std::vector<int> empty = {};
std::cout << empty …Run Code Online (Sandbox Code Playgroud) 我试图了解类型特征传播背后的机制,如http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0602r4.html 中std::optional 所述。复制操作的处理有细微的差别,复制操作应有条件地定义为删除,而移动操作则不应参与重载决议。
这种差异的原因是什么,我将如何测试后者?例子:
#include <type_traits>
#include <optional>
struct NonMoveable {
NonMoveable() = default;
NonMoveable(NonMoveable const&) = default;
NonMoveable(NonMoveable&&) = delete;
NonMoveable& operator=(NonMoveable const&) = default;
NonMoveable& operator=(NonMoveable&&) = delete;
};
// Inner traits as expected
static_assert(!std::is_move_constructible<NonMoveable>::value);
static_assert(!std::is_move_assignable<NonMoveable>::value);
// The wrapper is moveable, via copy operations participating in
// overload resolution. How to verify that the move operations don't?
static_assert(std::is_move_constructible<std::optional<NonMoveable>>::value);
static_assert(std::is_move_assignable<std::optional<NonMoveable>>::value);
int main(int argc, char* argv[])
{
NonMoveable a1;
NonMoveable a2{std::move(a1)}; // Bad, as expected
std::optional<NonMoveable> b1;
std::optional<NonMoveable> …Run Code Online (Sandbox Code Playgroud) 据我了解,函数名称使用的结果可能是以下之一:
\n= deleted, protected/private or, perhaps, something else) \xe2\x80\x94 the overall call is ill-formed.c++ well-formed ambiguous-call language-lawyer overload-resolution
考虑以下示例。标记的行上有两个函数模板(1),并(2)在行上调用(3)。两个模板都与调用相匹配,并且似乎没有一个比另一个更专业。
#include <utility>
template <int V, bool Enabled = true>
struct Version;
template <int V>
std::true_type Database(Version<V, V == 1>*); // (1)
template <int V>
std::false_type Database(Version<V>*); // (2)
using Winner = decltype(Database(std::declval<Version<1>*>())); // (3)
int foo()
{
return Winner::value;
}
Run Code Online (Sandbox Code Playgroud)
当然,我希望第 (3) 行会产生“不明确的调用”错误。但事实并非如此。gcc 13.2、clang 15.0 和 msvc v19.37 都选择重载 (2),没有错误。这是godbolt 在线示例。
问题是:为什么?我在部分排序和重载解析中缺少什么?
我有以下课程:
namespace {
class MimeLogger : public std::ostringstream
{
public:
MimeLogger()
{}
~MimeLogger()
{
LOGEVENT( logModuleWSE, logEventDebug, logMsgWSETrace1, str() );
}
};
}
Run Code Online (Sandbox Code Playgroud)
当我这样做:
MimeLogger() << "Hello " << "World";
Run Code Online (Sandbox Code Playgroud)
第一个"Hello "字符串被视为a void*.如果我调试代码,"Hello "则传入std::basic_ostream::operator<< (void const*)并打印为指针值,而不是字符串.第二个字符串,"World"正确地传递给全局重载的<<运算符,它接受一个char const*.
我希望<<运算符的两个用法都能解析为相同的重载,但这不会发生.有人可以解释,也许可以提出修复方案吗?
提前致谢.
我忽略了提到我坚持使用C++ 03,但我很高兴有些人同时介绍了C++ 03和C++ 11.
以下代码在编译时抛出"不明确的调用匹配":
class ABC{}
class DEF{}
class Program
{
static void Main(string[] args)
{
Debug.WriteLine(func(null));
}
static string func(ABC abc)
{
return "";
}
static string func(DEF def)
{
return "";
}
}
Run Code Online (Sandbox Code Playgroud)
但是下面的代码编译并运行正常:
static void Main(string[] args)
{
Debug.WriteLine(func(null));
}
static string func(int? abc)
{
return "function a";
}
static string func(float? def)
{
return "function b";
}
Run Code Online (Sandbox Code Playgroud)
输出
function a
Run Code Online (Sandbox Code Playgroud)
C#如何知道在第二个例子中选择哪个函数?
我在Internet和stackoverflow上进行了一些基本搜索,当涉及通用版本方法和非通用版本方法时,我看到了很多有关重载解析的讨论。我知道重载再分解是在编译时完成的-因此,如果我有以下代码:
public class A<T>
{
public void DoStuff(T value)
{
InternalDoStuff(value);
}
protected void InternalDoStuff(int value)
{
Console.WriteLine("Non-generic version");
}
protected void InternalDoStuff(T value)
{
Console.WriteLine("Generic version");
}
}
public class Test
{
static void Main (string [] args)
{
A<int> a = new A<int> ();
a.DoStuff(100);
}
}
Run Code Online (Sandbox Code Playgroud)
输出将是“通用版本”,因为编译器已经选择了“ InternalDoStuff”的分辨率,并且编译器看到的是“在DoStuff中使用T类型参数调用了InternalDoStuff”。
但是我不知道这是否会有所作为:
public class B : A <int>
{
}
public class Test
{
static void Main (string [] args)
{
B b = new B ();
b.DoStuff(100);
}
} …Run Code Online (Sandbox Code Playgroud)