Lem*_*rop 1 c++ type-traits language-lawyer c++17
最近,我尝试检测特定私有构造函数的存在,并遇到了std::is_constructible仅检查即时上下文而无法识别任何此类构造函数的问题。经过一些研究,我确实看到这里的一个答案提到,正确的方法是与有问题的班级交朋友,std::is_constructible以使其可以访问。
为了测试此方法是否有效,我尝试了以下测试代码
#include <type_traits>
class A {
private:
template<typename, typename ...>
friend struct std::is_constructible;
A() = default;
};
int main() {
static_assert(std::is_constructible<A>::value);
static_assert(std::is_constructible_v<A>);
}
Run Code Online (Sandbox Code Playgroud)
有趣的是,此方法std::is_constructible在Visual Studio 2017中似乎可以使用,尽管随后我开始遇到的问题std::is_constructible_v。在他们的实现中,std::is_constructible他们没有在实际的结构本身上使用别名模板,而是直接调用内部使用的内在函数,而内在函数又忽略了好友声明。
认为这是其标准库实现中的一个错误,然后我在其他编译器中进行了测试,发现无论是clang还是gcc在任何情况下都不能传递此断言,这使我想知道它是否应该像这样完全起作用(链接文章上的某些评论似乎暗示这是一个错误,而其他人则表示不应考虑朋友声明)。
因此,主要的问题是该代码是否应该正常工作(因为它应该能够访问私有构造函数并传递断言),并且该方法将标准定义的访问限制为立即上下文?这里也提出了类似的问题,我不确定的主要事情是这种情况下“即时上下文”所意图的确切定义,因为这与链接问题中的示例稍有不同。
N4713 23.15.4.3.8 [meta.unary.prop] / 8的相关段落:
就像在与T和任何Arg不相关的上下文中一样,执行访问检查。仅考虑变量初始化的即时上下文的有效性。