samedi 2 décembre 2017

overloading std::initializer_list confusion

I always thought that when I use initializer list C++ syntax like: something({ ... }); it's always clear to compiler that I want to call std::initializer_list overloaded version, but... it seems it's not so clear for MSVC 2015 :/

I tested this simple code:

#include <cstdio>
#include <initializer_list>

namespace testing {
  template<typename T>
  struct Test {
    Test() {
      printf("Test::Test()\n");
    }

    explicit Test(size_t count) {
      printf("Test::Test(int)\n");
    }

    Test(std::initializer_list<T> init) {
      printf("Test::Test(std::initializer_list)\n");
    }

    T* member;
  };

  struct IntSimilar {
    int val;

    IntSimilar() : val(0) {}
    IntSimilar(int v) : val(v) {}

    operator int() {
      return val;
    }
  };
}

int main() {
    testing::Test<testing::IntSimilar> obj({ 10 });
    return 0;
}

Run

and in gcc6.3 it works as expected: Test::Test(std::initializer_list) but in MSVC 2015 this code evaluates: Test::Test(int), it seems MSVC can somehow ignore {} and choose invalid/unexcepted version to call.

What does standard says about this situation? Which version is valid? So where is the evil? Does anybody can test this and confirm or not this issue in MSVC 2017?

Aucun commentaire:

Enregistrer un commentaire