overload-resolution

What are the pitfalls of ADL?

亡梦爱人 提交于 2019-11-26 16:05:27
Some time ago I read an article that explained several pitfalls of argument dependent lookup, but I cannot find it anymore. It was about gaining access to things that you should not have access to or something like that. So I thought I'd ask here: what are the pitfalls of ADL? There is a huge problem with argument-dependent lookup. Consider, for example, the following utility: #include <iostream> namespace utility { template <typename T> void print(T x) { std::cout << x << std::endl; } template <typename T> void print_n(T x, unsigned n) { for (unsigned i = 0; i < n; ++i) print(x); } } It's

Peculiar overload resolution with while (true)

一世执手 提交于 2019-11-26 10:34:43
问题 I was implementing sync/async overloads when I came across this peculiar situation: When I have a regular lambda expression without parameters or a return value it goes to the Run overload with the Action parameter, which is predictable. But when that lambda has a while (true) in it it goes to the overload with the Func parameter. public void Test() { Run(() => { var name = \"bar\"; }); Run(() => { while (true) ; }); } void Run(Action action) { Console.WriteLine(\"action\"); } void Run(Func

Why does pointer decay take priority over a deduced template?

自古美人都是妖i 提交于 2019-11-26 10:31:40
Let's say I'm writing a function to print the length of a string: template <size_t N> void foo(const char (&s)[N]) { std::cout << "array, size=" << N-1 << std::endl; } foo("hello") // prints array, size=5 Now I want to extend foo to support non -arrays: void foo(const char* s) { std::cout << "raw, size=" << strlen(s) << std::endl; } But it turns out that this breaks my original intended usage: foo("hello") // now prints raw, size=5 Why? Wouldn't that require an array-to-pointer conversion, whereas the template would be an exact match? Is there a way to ensure that my array function gets called

Overloaded method-group argument confuses overload resolution?

怎甘沉沦 提交于 2019-11-26 09:03:05
问题 The following call to the overloaded Enumerable.Select method: var itemOnlyOneTuples = \"test\".Select<char, Tuple<char>>(Tuple.Create); fails with an ambiguity error (namespaces removed for clarity): The call is ambiguous between the following methods or properties: \'Enumerable.Select<char,Tuple<char>> (IEnumerable<char>,Func<char,Tuple<char>>)\' and \'Enumerable.Select<char,Tuple<char>> (IEnumerable<char>, Func<char,int,Tuple<char>>)\' I can certainly understand why not specifying the type

Template partial ordering - why does partial deduction succeed here

最后都变了- 提交于 2019-11-26 08:23:28
问题 Consider the following simple (to the extent that template questions ever are) example: #include <iostream> template <typename T> struct identity; template <> struct identity<int> { using type = int; }; template<typename T> void bar(T, T ) { std::cout << \"a\\n\"; } template<typename T> void bar(T, typename identity<T>::type) { std::cout << \"b\\n\"; } int main () { bar(0, 0); } Both clang and gcc print \"a\" there. According to the rules in [temp.deduct.partial] and [temp.func.order], to

Overload resolution and virtual methods

那年仲夏 提交于 2019-11-26 08:23:09
问题 Consider the following code (it\'s a little long, but hopefully you can follow): class A { } class B : A { } class C { public virtual void Foo(B b) { Console.WriteLine(\"base.Foo(B)\"); } } class D: C { public override void Foo(B b) { Console.WriteLine(\"Foo(B)\"); } public void Foo(A a) { Console.WriteLine(\"Foo(A)\"); } } class Program { public static void Main() { B b = new B(); D d = new D (); d.Foo(b); } } If you think the output of this program is \"Foo(B)\" then you\'d be in the same

String literal matches bool overload instead of std::string

ぃ、小莉子 提交于 2019-11-26 04:25:27
问题 I am trying to write a C++ class that has some overloaded methods: class Output { public: static void Print(bool value) { std::cout << value ? \"True\" : \"False\"; } static void Print(std::string value) { std::cout << value; } }; Now lets say I call the method as follows: Output::Print(\"Hello World\"); this is the result True So, why, when I have defined that the method can accept boolean and string, does it use the boolean overload when I pass in a non-boolean value? EDIT: I come from a C#

Why does pointer decay take priority over a deduced template?

隐身守侯 提交于 2019-11-26 02:09:51
问题 Let\'s say I\'m writing a function to print the length of a string: template <size_t N> void foo(const char (&s)[N]) { std::cout << \"array, size=\" << N-1 << std::endl; } foo(\"hello\") // prints array, size=5 Now I want to extend foo to support non -arrays: void foo(const char* s) { std::cout << \"raw, size=\" << strlen(s) << std::endl; } But it turns out that this breaks my original intended usage: foo(\"hello\") // now prints raw, size=5 Why? Wouldn\'t that require an array-to-pointer

How does the method overload resolution system decide which method to call when a null value is passed?

生来就可爱ヽ(ⅴ<●) 提交于 2019-11-26 00:44:03
问题 So for instance you have a type like: public class EffectOptions { public EffectOptions ( params object [ ] options ) {} public EffectOptions ( IEnumerable<object> options ) {} public EffectOptions ( string name ) {} public EffectOptions ( object owner ) {} public EffectOptions ( int count ) {} public EffectOptions ( Point point ) {} } Here I just give the example using constructors but the result will be the same if they were non-constructor methods on the type itself, right? So when you do: