标签: overload-resolution

为什么将NULL转换为字符串*?

我看到了以下代码:

class NullClass {
public:
    template<class T> operator T*() const { return 0; }
};

const NullClass NULL;

void f(int x);
void f(string *p);

f(NULL); // converts NULL to string*, then calls f(string*)
Run Code Online (Sandbox Code Playgroud)

Q1>我有理由理解以下声明

template<class T> operator T*() const { return 0; }
Run Code Online (Sandbox Code Playgroud)

特别是,是什么意思operator T*()

Q2>为什么f(NULL)最终触发f(string*)

谢谢

c++ templates overloading overload-resolution

4
推荐指数
1
解决办法
296
查看次数

Visual Studio错误解决方法中的lambda与Func委托重载?

在具有各种Func委托重载的函数中使用匿名方法时,我在Visual Studio 2010中遇到了一些奇怪的行为.

我在下面创建了一个小型复制课程.

考虑这个ListViewAdapter类

namespace LambdaTestApp
{
    public class ListViewAdapter<T>
    {
        private Func<int, string, int, string> _converter1;
        private Func<RefType1, string, string> _converter2;

        public ListViewAdapter(int arg1, Func<int, string, int, string> converter) 
        {
            _converter1 = converter;
        }

        public ListViewAdapter(int arg1, Func<RefType1, string, string> converter) 
        {
            _converter2 = converter;
        }

        public static ListViewAdapter<T> MockPopulate(int arg, Func<int, string, int, string> converter) {

            ListViewAdapter<T> instance = new ListViewAdapter<T>(arg, converter);

            return instance;
        }

        public static ListViewAdapter<T> MockPopulate(int arg, Func<RefType1, string, string> converter)
        {
            ListViewAdapter<T> instance …
Run Code Online (Sandbox Code Playgroud)

c# lambda func visual-studio overload-resolution

4
推荐指数
1
解决办法
480
查看次数

在C#中解决方法重载的优先规则是什么?

我正在编写一个序列化程序,我希望广泛使用方法重载,序列化派生类型的对象IEnumerable<T>,IDictionary<K,V>等等.

我还打算使用dynamic关键字让C​​LR根据要序列化的对象的运行时类型选择正确的重载.

看看这段代码:

void Serialize<TKey, TValue>(IDictionary<TKey, TValue> dictionary)
{
  Console.WriteLine("IDictionary<TKey, TValue>");
}

void Serialize<TKey, TValue>(IEnumerable<KeyValuePair<TKey, TValue>> items)
{
  Console.WriteLine("IEnumerable<KeyValuePair<TKey, TValue>>");
}

void Serialize<T>(IEnumerable<T> items)
{
  Console.WriteLine("IEnumerable<T>");
}
Run Code Online (Sandbox Code Playgroud)

我想这样做:

void CallSerialize(object obj)
{
   Serialize(obj as dynamic); //let the CLR resolve it at runtime.
}
Run Code Online (Sandbox Code Playgroud)

现在基于运行时类型obj,将调用正确的重载.例如,

//Test code
CallSerialize(new List<int>()); //prints IEnumerable<T>
Run Code Online (Sandbox Code Playgroud)

在这种情况下,调用第三个重载并且基本原理非常简单:这只是可行的选项.

但是,如果我这样做:

CallSerialize(new Dictionary<int,int>()); //prints IDictionary<TKey, TValue>
Run Code Online (Sandbox Code Playgroud)

它调用第一个重载.我不太明白这一点.当所有三个过载都是可行的选项时,为什么它会解决第一个过

实际上,如果我删除第一个,则调用第二个重载,如果我删除第一个和第二个重载,则调用第三个重载.

解决方法重载的优先顺序是什么?

c# overloading dynamic overload-resolution

4
推荐指数
1
解决办法
212
查看次数

当您想要更改的所有内容都是返回类型时,重载方法的最佳方法

由于返回类型不能用于消除方法的歧义,当你想要改变的只是返回类型时,什么是最简洁/最好的方法来重载方法?下面是一些示例代码;

public static string Get(string url, Guid id, bool logResponse = true, bool baseKey = false)
{
     Tuple<string, int> response = Get(url, id, true, logResponse, baseKey);

     if (response.Item2 > 399)
        return null;
     return response.Item1;
}


public static Tuple<string, int> Get(string url, Guid id, bool returnStatus, bool logResponse = true, bool baseKey = false)
{
    // leaving out lots of code in this method, you should be able to get the point without it
    int http_status;  
    string response = CallApi(url, key, …
Run Code Online (Sandbox Code Playgroud)

.net c# overloading overload-resolution

4
推荐指数
1
解决办法
323
查看次数

试图了解如何选择重载函数

我有以下程序:

#include <iostream>

namespace detail {

    template <class T> char test(int T::*)
    {
       std::cout << "Came to one\n";
       return 0;
    }

    template <class T> int test(...)
    {
       std::cout << "Came to two\n";
       return 0;
    }
}

struct A {};

int main()
{
   detail::test<A>(0);
   detail::test<int>(0);
}
Run Code Online (Sandbox Code Playgroud)

使用g ++ 4.8.2进行测试时,会产生以下输出:

Came to one
Came to two

我的问题:为什么第detail::test一个电话会明确选择第一个版本?

更新

在没有第一个版本的情况下details::test,main编译好的代码.当它存在时,编译器认为它detail::test<A>()比第二个更好.

更新2

在阅读了关于成员的指针之后,即使对于不完整类型或没有指定类型的成员,也是格式良好的.,我尝试了以下,它的工作原理.

struct A;

int main()
{
   detail::test<A>(0);
   detail::test<int>(0);
}
Run Code Online (Sandbox Code Playgroud)

C++ 11标准有很多地方可以发现我不会想到的概念.

c++ templates g++ overload-resolution c++11

4
推荐指数
1
解决办法
174
查看次数

C++ 11 lvalue,rvalue和std :: move()

我有以下代码:

#include <iostream>
using namespace std;
void test(int& a) {
    cout << "lvalue." << endl;
}
void test(int&& a) {
    cout << "rvalue" << endl;
}
int main(int argc, char *argv[]) {
    int a = 1;
    int&& b = 2;
    test(a);
    test(1);
    test(std::move(a));
    test(b);
}
Run Code Online (Sandbox Code Playgroud)

哪个输出:

lvalue.
rvalue
lvalue.
lvalue.
Run Code Online (Sandbox Code Playgroud)

std::move()并且int&&是右值参考,我想知道为什么test(std::move(a))test(b)输出lvalue?它与签名匹配和函数重载有关吗?

c++ rvalue overload-resolution c++11

4
推荐指数
1
解决办法
1039
查看次数

为什么我的函数超载不是我的模板优先?

根据这个问题的第一个答案:函数模板重载,"非模板化(或"模板化程度较低")重载优于模板".

#include <iostream>
#include <string>
#include <functional>

void f1 (std::string const& str) {
    std::cout << "f1 " << str << std::endl;
}

template <typename Callback, typename... InputArgs>
void call (Callback callback, InputArgs ...args) {
    callback(args...);
}

void call (std::function<void(std::string const&)> callback, const char *str) {
    std::cout << "custom call: ";
    callback(str);
}

int main() {
    auto f2 = [](std::string const& str) -> void {
        std::cout << "f2 " << str << std::endl;
    };

    call(f1, "Hello World!"); …
Run Code Online (Sandbox Code Playgroud)

c++ templates overload-resolution c++11

4
推荐指数
1
解决办法
257
查看次数

奇怪的扩展方法重载决议

我无法让编译器解决扩展方法的正确重载问题.我解释的最好方法是使用一些代码.这是一个演示问题的LINQPad脚本.由于我遇到的问题,这将无法编译:

void Main(){
    new Container<A>().Foo(a=>false);
}

interface IMarker{}
class A : IMarker{
    public int AProp{get;set;}
}
class B : IMarker{
    public int BProp{get;set;}
}
class Container<T>{}

static class Extensions{
    public static void Foo<T>(this T t, Func<T, bool> func)
        where T : IMarker{
        string.Format("Foo({0}:IMarker)", typeof(T).Name).Dump();
    }
    public static void Foo<T>(this Container<T> t, Func<T, bool> func){
        string.Format("Foo(Container<{0}>)", typeof(T).Name).Dump();
    }
}
Run Code Online (Sandbox Code Playgroud)

我得到的错误是:

以下方法或属性之间的调用不明确:' Extensions.Foo<Container<A>>(Container<A>, System.Func<Container<A>,bool>)'和' Extensions.Foo<A>(Container<A>, System.Func<A,bool>)'

在我看来,它根本不含糊.第一种方法不接受a Container<T>,只接受a IMarker.似乎通用约束不能帮助解决重载,但在这个版本的代码中,它们似乎确实如下:

void Main(){
    new A().Bar();
    new A().Foo(a=>a.AProp == …
Run Code Online (Sandbox Code Playgroud)

c# extension-methods overload-resolution

4
推荐指数
1
解决办法
381
查看次数

为什么F#不能解决Async <>和Async <Result <>>之间的重载问题?

我想在特定的上下文中更好地理解F#重载决策.

我正在编写一个简单的asyncResult工作流程/计算表达式,以便在与异步工作流程结合使用时,以面向铁路的编程风格更容易使用错误处理.我通过Bind在工作流构建器上重载方法来完成此操作.这是相当标准的,并且在我看过的所有指南中使用(并且也用于例如Chessie/ErrorHandling.fs).

我有一个接受一个Async<_>和一个接受一个的重载Result<_,_>.现在,理想情况下,我想接受第三个重载Async<Result<_,_>>.然而,当我尝试使用let!do!与返回表达式Async<'a>,F#抱怨独特的超载不能确定,因为这两个Async<_>Async<Result<_,_>>配合,这当然他们这样做(虽然其中一个比另一个更适合明确).我似乎能够做到这一点的唯一方法就是像Chessie(上面的链接)那样做并定义一个包装类型:

type AsyncResult<'a, 'b> = AR of Async<Result<'a, 'b>>
Run Code Online (Sandbox Code Playgroud)

这再次要求我将所有调用包装到Async<Result<_,_>>以这种新类型返回的方法中:

asyncResult {
  let! foo = funcReturningResultInsideAsync() |> AR
  ...
}
Run Code Online (Sandbox Code Playgroud)

AFAIK,C#将选择最具体的过载.如果F#做了同样的事情,这不会有问题.

  1. 为什么F#不能选择最具体的过载?
  2. 在这种特定情况下可以采取任何措施来避免包装类型吗?

编辑:根据评论中的要求,这里是非编译代码,显示我理想的内容,但不起作用.

module AsyncResult =

  let liftAsync x = 
    async { return x }

  let pure (value: 'a) : Async<Result<'a, 'b>> = 
    async { return Ok value }

  let returnFrom (value: …
Run Code Online (Sandbox Code Playgroud)

f# overload-resolution

4
推荐指数
2
解决办法
358
查看次数

从过载集中调用具有特定函数的仿函数

上下文

在与数学相关的上下文中,我想定义函数的函子<cmath>.出于这个问题的目的,我们将使用std::invoke作为我们的函子.

这是不正确的(现场演示):

std::invoke(std::sin, 0.0);
Run Code Online (Sandbox Code Playgroud)

(g ++ - 8.1)错误:没有用于调用'invoke(<unresolved overloaded function type>,double)'的匹配函数

实际上,std::sin是一个重载集,编译器缺少类型信息来选择其中一个函数.

如何从重载集中命名特定函数?我们可以取代什么LEFT,RIGHT以便以下是良好的形式,并做出预期(例如,选择double std::sin(double))?

#include <functional>
#include <cmath>

int main()
{
    (void) std::invoke(LEFT std::sin RIGHT, 0.0);
}
Run Code Online (Sandbox Code Playgroud)

如果这是不可能的,有没有办法定义一个仿函数,所以它是重载集感知?

c++ overloading overload-resolution c++17

4
推荐指数
1
解决办法
200
查看次数