标签: overload-resolution

Mockito:使用类型兼容的参数验证重载方法

考虑您想要使用包含以下方法签名来模拟接口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)进行验证?

java eclipse mockito overload-resolution ecj

6
推荐指数
1
解决办法
5986
查看次数

构造函数和转换运算符之间的重载解析

我有几个与 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.cppA的构造函数将被调用:

A<T>::A(A<U>&&) [with U = int; T = X] 
Run Code Online (Sandbox Code Playgroud)

如果我用 编译程序g++ -std=c++17 …

c++ language-lawyer overload-resolution

6
推荐指数
1
解决办法
140
查看次数

您可以(并且应该)消除使用 T 和 const 引用 T 的函数调用的歧义吗?

如果我们有:

void foo(int) {}
void foo(const int&) {}
Run Code Online (Sandbox Code Playgroud)

我们不能这样调用foo

foo(3);
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&) {}
   |      ^~~
Run Code Online (Sandbox Code Playgroud)

我们可以做的是明确提供正确的重载,例如通过函数指针:

auto (*ptr)(const int&) -> void = foo;
ptr(3); // calls the "const int&" overload, obviously
Run Code Online (Sandbox Code Playgroud)

然而,这种方式违背了方便重载的目的。问题是 - 我可以以某种方式以更......优雅的方式消除呼叫的歧义吗?道路?是否有哪里会需要提供案件过载,为Tconst T& …

c++ overload-resolution

6
推荐指数
1
解决办法
118
查看次数

为什么 const char[] 与 std::ranges::range 的匹配比显式的 const char* 自由重载更好,以及如何修复它?

我想<<为任何人写一个泛型,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)

它完美运行并输出:

[1,2,3,4]
Run Code Online (Sandbox Code Playgroud)

但是,当测试时:

int main() {
    std::vector<int> empty = {};
    std::cout << empty …
Run Code Online (Sandbox Code Playgroud)

c++ overload-resolution c++-concepts c++20 std-ranges

6
推荐指数
1
解决办法
152
查看次数

std::optional:不参与重载决议与被定义为已删除

我试图了解类型特征传播背后的机制,如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)

c++ optional overload-resolution

6
推荐指数
1
解决办法
280
查看次数

如何检查给定参数类型,隐式使用“operator ()”是否会产生一个最佳可行候选者?

据我了解,函数名称使用的结果可能是以下之一:

\n
    \n
  1. 没有(最佳)可行的函数 \xe2\x80\x94 重载解析失败。子结果是:\n
      \n
    1. 没有候选人。
    2. \n
    3. There are some candidates, just none are viable.
    4. \n
    \n
  2. \n
  3. There is exactly one best viable function \xe2\x80\x94 overload resolution succeeds. The selected overload is then either\n
      \n
    1. OK \xe2\x80\x94 the overall call is well-formed.
    2. \n
    3. not OK (= deleted, protected/private or, perhaps, something else) \xe2\x80\x94 the overall call is ill-formed.
    4. \n
    \n
  4. \n
  5. There are more than one best viable functions \xe2\x80\x94 overload resolution fails …

c++ well-formed ambiguous-call language-lawyer overload-resolution

6
推荐指数
0
解决办法
89
查看次数

为什么对重载函数模板的调用不存在二义性?

考虑以下示例。标记的行上有两个函数模板(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 在线示例

问题是:为什么?我在部分排序和重载解析中缺少什么?

c++ templates overload-resolution c++17

6
推荐指数
1
解决办法
78
查看次数

std :: ostringstream运算符重载搜索顺序?

我有以下课程:

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.

c++ stl overload-resolution

5
推荐指数
1
解决办法
284
查看次数

模糊调用匹配混乱

以下代码在编译时抛出"不明确的调用匹配":

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#如何知道在第二个例子中选择哪个函数?

c# null nullable overload-resolution

5
推荐指数
1
解决办法
2188
查看次数

通用方法与非通用方法之间的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)

c# generics overload-resolution

5
推荐指数
1
解决办法
2886
查看次数