MSVC使用constexpr if在可变参数模板方法中吞下const的基本模板参数

Seb*_*n.M 8 c++ visual-c++ variadic-templates if-constexpr

我有一个问题,我几乎可以肯定是一个MSVC错误,但也许我错过了一些东西.

这是实际代码的简化版本:

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...>) {}
};
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,唯一的区别foo1()foo2()是constexpr如果.当我尝试在MSVC中编译一些测试时会发生以下情况:

 OuterType<const bool> test1;
 test1.foo1(); // does not compile
 test1.foo2(); // compiles

 OuterType<bool> test2;
 test2.foo1(); // compiles
 test2.foo2(); // compiles
Run Code Online (Sandbox Code Playgroud)

我得到的错误test1.foo1()是:

error C2664: 'void OuterType<const bool>::bar(InnerType<const bool>)':
cannot convert argument 1 from 'InnerType<bool>' to 'InnerType<const bool>'
Run Code Online (Sandbox Code Playgroud)

在使用GCC的Linux上,相同的代码编译没有问题.此外,尝试使用非基本类型也可以在MSVC中工作:

 class SomeType {};

 OuterType<const SomeType> test;
 test.foo1(); // compiles
 test.foo2(); // compiles
Run Code Online (Sandbox Code Playgroud)

因此,出于某种原因,当使用constexpr if和const基本类型作为模板参数时,它const会被吞噬.当它不是可变参数模板时,不会发生此问题.

是一个实例.

我是否正确地认为它是编译器错误?

Seb*_*n.M 0

结果证明这是一个错误。对于遇到同样问题的人,微软表示他们将在 VS 15.8 Preview 4 中修复该问题。