【发布时间】:2017-09-10 18:25:51
【问题描述】:
我目前正在与 Visual Studio 2017 搏斗(如果有帮助,请使用 /std:c++latest 进行编译)。
有问题的代码只是根据一些模板化的constexpr 函数的结果选择一个结构特化。 GCC 和 clang 编译都没有问题。
这是我的 MCVE:
#include <type_traits>
struct A {
enum {
test_trait = true
};
};
template<typename T>
constexpr int choose() {
return T::test_trait;
}
template<typename T, typename Enable=void>
struct Chosen;
template<typename T>
struct Chosen<T, std::enable_if_t<choose<T>() == 1>> {};
void foo() {
// This works
constexpr int chosen = choose<A>();
static_assert(chosen == 1, "");
// This resolves to the undefined struct.
using Chosen_t = Chosen<A>;
Chosen_t x;
(void)x;
}
choose() 在我的代码库中实际上要复杂一些,但static_assert 仍然可以编译,并且检查正常。
我有点假设如果 static_assert 编译,enable_if 没有理由不能发挥它的魔力。我错了吗?我猜“也许”T 在技术上不是enable_if 的依赖类型...但如果是这样的话,我希望 GCC 和 clang 会拍我的手腕。
我可以通过将choose() 的结果包装在std::integral_constant 中来解决这个问题,如下所示:
template<typename T>
struct Chooser : public std::integral_constant<int, choose<T>()> {};
template<typename T>
struct Chosen<T, std::enable_if_t<Chooser<T>::value>> {};
但我真的不想跳过那个圈子。
模板解析应该能够以我期望的方式解决这个问题吗?我担心代码实际上是错误的,而 GCC 和 clang 只是对我宽容。
【问题讨论】:
-
这适用于 VS 2015 吗?这可能是与this相关的错误
-
@Justin 刚刚检查:没有,Visual Studio 2015 似乎有同样的错误。
-
VC++ 在模板方面被严重破坏了。代码完全没问题。采用您的解决方法并收工?
-
@Columbo,如果我的代码不能以可移植的方式使用,我不会称它为“好” :(。但是,不幸的是,我想这将不得不这样做。跨度>
标签: c++ visual-studio c++14 constexpr enable-if