8

我有一个问题,我几乎可以肯定是一个 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...>) {}
};

如您所见,foo1()和之间的唯一区别foo2()是 constexpr if。以下是我尝试在 MSVC 中编译一些测试时发生的情况:

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

 OuterType<bool> test2;
 test2.foo1(); // compiles
 test2.foo2(); // compiles

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

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

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

 class SomeType {};

 OuterType<const SomeType> test;
 test.foo1(); // compiles
 test.foo2(); // compiles

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

是一个活生生的例子。

我是否正确地假设它是一个编译器错误?

4

1 回答 1

0

所以它原来是一个错误。对于遇到相同问题的任何人,微软表示他们将在 VS 15.8 Preview 4 中修复它。

于 2018-07-20T09:31:44.710 回答