I have a problem that I'm almost certain is a MSVC bug, but maybe I'm missing something.
Here is a simplified version of the actual code:
template <typename... Args>
class InnerType {};
template <typename... Args>
class OuterType {
public:
void foo1() {
if constexpr (true) {
bar(InnerType<Args...>());
}
}
void foo2() {
if (true) {
bar(InnerType<Args...>());
}
}
void bar(InnerType<Args...>) {}
};
As you can see, the only difference between foo1()
and foo2()
is the constexpr if. Here is what happens when I try to compile some tests in MSVC:
OuterType<const bool> test1;
test1.foo1(); // does not compile
test1.foo2(); // compiles
OuterType<bool> test2;
test2.foo1(); // compiles
test2.foo2(); // compiles
The error I get for test1.foo1()
is:
error C2664: 'void OuterType<const bool>::bar(InnerType<const bool>)':
cannot convert argument 1 from 'InnerType<bool>' to 'InnerType<const bool>'
The same code compiles without a problem on Linux using GCC. Additionally, trying the same with a non-fundamental type works in MSVC as well:
class SomeType {};
OuterType<const SomeType> test;
test.foo1(); // compiles
test.foo2(); // compiles
So it seems that for some reason when using constexpr if and a const fundamental type as template parameter the const
gets swallowed. The problem does not occur when it's not a variadic template.
Here is a live example.
Am I right in assuming that it's a compiler bug?
So it turned out to be a bug. For anyone experiencing the same issue, Microsoft said they will have it fixed in VS 15.8 Preview 4.