c++ - MSVC 无法编译以私有(private)类型作为参数的显式模板实例化

标签 c++ gcc visual-c++ clang explicit-instantiation

考虑以下示例,包含 4 个文件。



Outer.h

#pragma once

#include "genericAlgorithm.h"

class Outer
{
private:
    struct Inner {};    // Note that Inner is private

    const Inner inner;

public:
    Outer() : inner() {}

    inline void method()
    {
        genericAlgorithm(inner);
    }
};


genericAlgorithm.h

#pragma once

template <typename T>
void genericAlgorithm(const T& value);


genericAlgorithm.cpp

#include "genericAlgorithm.h"

#include "Outer.h"

template <typename T>
void genericAlgorithm(const T& value) {}

// Explicit template instantiation (compiles on GCC, Clang; error C2248 on MSVC)
template void genericAlgorithm<Outer::Inner>(const Outer::Inner& value);


ma​​in.cpp

#include "Outer.h"

int main()
{
    Outer outer;
    outer.method();
    return 0;
}

如您所见,在 genericAlgorithm.cpp 中有一个显式实例化 genericAlgorithm() 参数 Outer::Inner 函数模板,它是 Outer 类的私有(private)内部结构。

据我了解,这是合法的,因为根据 cppreference.com ...

Explicit instantiation definitions ignore member access specifiers: parameter types and return types may be private.

事实上,这段代码在 GCC 6.3 和 Clang 4.0 上编译得非常好。

但是,MSVC (Visual Studio 2017 15.2) 似乎对此有异议并产生以下编译错误:

genericalgorithm.cpp(9): error C2248: 'Outer::Inner': cannot access private struct declared in class 'Outer'

那么,这是 MSVC 中的一个错误,还是我遗漏了什么,实际上我的代码有问题需要修复?如果是这样,是否意味着 GCC 和 Clang 以及 cppreference.com 错了?


更新:我相信我在标准的 n4296n4567 工作草案的 §14.7.2 [templ.explicit](第 12 项)中找到了相关段落:

The usual access checking rules do not apply to names used to specify explicit instantiations. [Note: In particular, the template arguments and names used in the function declarator (including parameter types, return types and exception specifications) may be private types or objects which would normally not be accessible and the template may be a member template or member function which would not normally be accessible. — end note]

除非我误解了所写的内容,否则 MSVC 的这种行为似乎确实不合规。当然,这些只是草稿 - 很遗憾,我无法访问实际的 $133 per copy 标准,因此我无法确定该项目是否已被保留。

最佳答案

我认为这意味着显式实例化定义忽略了您显式指定 中的访问说明符。它不会神奇地授予您访问其他项目的私有(private)成员的权限。

类型“Inner”对于您用作参数的事物是私有(private)的,而不是类型 genericAlgorithm

关于c++ - MSVC 无法编译以私有(private)类型作为参数的显式模板实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47142451/

相关文章:

c# - 配置基于 .NET 的组件以实现免注册激活

c++ - 当一个对象的死亡导致另一个对象生病时如何保持封装

c# - block 分配

c++ - 如何通过在 C++ 中的 [] 中传递变量来定义数组的大小?

c - 为什么这些 C 结构定义会给出警告和错误?

visual-c++ - 奇怪的 VC10 链接器错误

c++ - 编译 Mongodb 3.6.5 以插入到 Docker 镜像中

c++ - AVX 类型的 C++ 内部函数的引用和在线资源

windows - 为什么 Visual Studio 2008 找不到 afxcontrolbars.h?

c++ - CPrintDialog::OnInitDialog 不会每次都被调用