为什么这种部分特化会产生编译器错误(SFINAE问题)

时间:2015-11-02 14:03:02

标签: c++ sfinae

有人可以确认下面的部分专业化是否应该放在main()的第1行(针对Visual Studio 2013和/或2015)。

#include "stdafx.h"
#include <type_traits>
#include <vector>
#include <utility>

using Iter = std::vector<int>::const_iterator;

template<typename, typename = void >
struct IsIterator : std::false_type
{
    using primary = bool;
};

template<typename T>
struct IsIterator< T, std::enable_if_t< !std::is_void<decltype(*std::declval<T>())>::value > >
    : std::true_type
{
    using partial = bool;
};

int main()
{
    IsIterator<Iter>::partial whatever; // LINE 1
    bool test = !std::is_void<decltype(*std::declval<Iter>())>::value; // LINE 2

    return 0;
}

我认为它应该基于标准,但是LINE 1在VS2013中失败并出现“内部编译器”错误,而在VS2015中失败并出现以下情况:

'partial': is not a member of 'IsIterator<Iter,void>'

因此我仅限于在VS 2015中测试它(由于VS2013中的内部编译器错误),但即使在VS2015中,当设置为“primary”时编译也很好,这对我来说似乎不正确。它应该是“部分”的AFAIK。此外:

    http://coliru.stacked-crooked.com/ 编译时,
  1. “partial”被认为是正确的
  2. 如果在main()中注释掉LINE 1以消除错误,那么LINE 2会按预期返回true(在专业化中看到相同的代码),所以我不希望在LINE 1时出现上述错误 取消注释(专业化应该启用,因此partial应该存在)
  3. Visual Studio的Intellisense有时会向我显示“部分”是正确的,有时则是不正确的。即使向我展示它是正确的,但编译仍然失败。这种行为是片状的,我可以重现一个明确的错误。
  4. 如果我只是替换 !std::is_void<decltype(*std::declval<T>())>::value true与{1}}进行编译,然后将LINE 1设置为partial
  5. 在我看来,“部分”基于标准适用(有人可以确认这一点),如果是这样,那么Visual Studio有一个错误(而不仅仅是Intellisense错误)。这种类型的代码可能非常微妙,但也许有人可以放弃一些光(如果我错过了什么)。感谢。

0 个答案:

没有答案