8

I just realized that trying to get the return type of a function via decltype does not involve ADL (argument-dependent-lookup) on VS2012 (tested using cl.exe V17.00.60610.1).

The following example

#include <stdio.h>
#include <typeinfo>

namespace A {
  int Func(void const *) {
    printf("A::Func(void const *)\n");
    return 0;
  }

  template <typename T> void Do(T const &t) {
    Func(&t);
  }
  template <typename T> void PrintType(T const &t) {
    printf("Type: %s\n", typeid(decltype(Func(&t))).name());
  }
}

namespace B {
  struct XX { };
  float Func(XX const *) {
    printf("B::Func(XX const *)\n");
    return 0.0f;
  }
}


int main(int argc, char **argv) {
  B::XX xx;
  A::Do(xx);
  A::PrintType(xx);
  return 0;
}

Gives

B::Func(XX const *)
Type: int

on VS2012

but (what is expected):

B::Func(XX const *)
Type: f

on gcc 4.7.3.

So ADL works when calling the function (line 1 in output) but not when used inside decltype on VS2012.

Or am I missing some different point?

mmmmmmmm
  • 15,269
  • 2
  • 30
  • 55
  • 2
    VS2012 `decltype` support is pretty poor (search for "expression SFINAE" and weep), so I'm not all that surprised. – Yakk - Adam Nevraumont Jul 16 '13 at 13:07
  • many C++11 features were very much of alpha-quality in VS2012 and the subsequent November CTP. Supposedly there is a long list of fixed bugs in VS2013 preview (Express currently available for download). You might try your luck there. – TemplateRex Jul 16 '13 at 18:55
  • So what about the new way of very frequent updates to solve bugs and add new features that MS wanted to follow since VS2012... So what...fortunately I'm unrestricted in my compiler selection in this specific project so all my hopes and dreams are pinned on VS2013 :-) – mmmmmmmm Jul 17 '13 at 08:46

2 Answers2

2

A minimal test case is:

namespace N
{
    struct C {};

    C f(C) {};
}

N::C c1;

decltype(f(c1)) c2;

If the compiler doesn't support ADL inside decltype, then the above will not compile.

I'm told it does compile, so maybe it is the interaction between ADL and template instantiation that is the problem.

Andrew Tomazos
  • 66,139
  • 40
  • 186
  • 319
  • If `c1` is declared with the namespace `N::C c1; and `c2` as a function (since MSVS will not accept a variable of type `void`), it compiles. – Pixelchemist Jul 16 '13 at 19:39
  • @Pixelchemist: Fixed, thanks. If MSVS does compile it, then msvs doesn't have a problem with ADL inside decltype in at least some cases. – Andrew Tomazos Jul 16 '13 at 19:42
2

If find it amusing that the IDE/Intellisense whatsoever seems to do the lookup correctly but the compiler does not.

This example shows no intellisense errors and a is displayed to be of type size_t when hovering it.

#include <iostream>
namespace A
{
    struct C {};
    size_t f(C*) { return 5U; };
}
namespace B
{
  void f(void *) { };
  void f2 (A::C x) 
  {  decltype(f(&x)) a; std::cout << typeid(a).name() << std::endl; }
}

int main (void) 
{ 
  A::C c;
  B::f2(c);
}

The compiler stops with Error C2182 and complains about a variable of type void. It seems to be a problem independant of templates.

Pixelchemist
  • 24,090
  • 7
  • 47
  • 71
  • Visual C++ uses a different C++ frontend for IntelliSense and IDE features, so there are many subtle differences between what IntelliSense accepts and what the compiler accepts. – James McNellis Jul 16 '13 at 20:05
  • Thanks for the info. I'm not quite surprised but amused. I just wanted to give the hint that the templates are not the problem here. – Pixelchemist Jul 16 '13 at 20:08