使用 MSVC 获取“实例化导致未执行的类型”

问题描述 投票:0回答:1

在我的一个库中,我有以下代码(为简洁起见,进行了剪辑):

namespace memory {
namespace managed {

namespace detail {

template <typename T>
inline T get_scalar_range_attribute(
    region_t region,
    cudaMemRangeAttribute attribute)
{ /* snip */ }

} // namespace detail

struct region_t : public memory::region_t {
    // snip
    bool is_read_mostly() const
    {
        return detail::get_scalar_range_attribute<bool>(
            *this, cudaMemRangeAttributeReadMostly);
    }

    // snip
}

} // namespace managed
} // namespace memory

现在,使用 Linux 上的 GCC 和 Clang,这可以正常工作。但在 Windows 上使用 MSVC 16.8.4 时,我的一个用户得到:

error : template instantiation resulted in unexpected function type of "__nv_bool
(cuda::memory::managed::region_t, cudaMemRangeAttribute)" (the meaning of a name
may have changed since the template declaration -- the type of the template is "T
(cuda::memory::region_t, cudaMemRangeAttribute)"

我不明白实例化如何会导致意外的结果。我也不明白我的一个类名与另一个类名的“名称隐藏”会对模板实例化产生任何影响。

c++ visual-c++ compiler-errors cuda compiler-bug
1个回答
2
投票

(这大部分归功于@Guillaume Racicot。)

这里的问题是名称查找的时间。

其他编译器,当遇到模板声明时,

region_t
,似乎会寻找先前定义的
region_t
;找到
memory::region_t
;并对此表示同意。 (如果我错了请纠正我)。

然而,MSVC 执行查找两次:一次是在遇到声明+定义时,然后是在实例化时再次查找 - 两次都使用不同的上下文。所以,第一次,它找到了

memory::region_t

;第二次它找到
memory::managed::region_t
。这真是“意料之外”……

MSVC 的这种行为显然是由于其“宽容”编译模式(默认情况下启用)造成的。这有点奇怪,看看在这种情况下它是如何

less宽容的:-(

© www.soinside.com 2019 - 2024. All rights reserved.