Search code examples
c++visual-c++variadic-templatesif-constexpr

MSVC swallows const from fundamental template parameter in variadic template methods using constexpr if


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?


Solution

  • 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.