C++ 作为NTTP的结构类型:为什么所有构件都必须是公共的?

C++ 作为NTTP的结构类型:为什么所有构件都必须是公共的?,c++,templates,c++20,C++,Templates,C++20,在下面的示例中 template<auto V> struct A {}; struct B { constexpr B(int a) : value{a} {} private: int value{0}; }; int main() { constexpr B b{0}; A<b> t2; } 模板?答案很简单,但令人失望:C++20不允许这样做。最终c++23将引入更广泛的解决方案 这是[P1907]的真实意图吗

在下面的示例中

template<auto V>
struct A {};

struct B {
    constexpr B(int a) : value{a} {}
private:
    int value{0};
};

int main() {
    constexpr B b{0};
    A<b> t2;        
}

模板?

答案很简单,但令人失望:C++20不允许这样做。最终c++23将引入更广泛的解决方案

这是[P1907]的真实意图吗

P1907的目的是正确指定在模板参数上下文中两个值相等的含义。在本文之前,等价概念首先基于<代码> <代码>(),然后基于<代码>=(),但是使用这些比较运算符作为基础有很多问题(如文中所述)。 考虑指针。我们已经有很长一段时间的写作能力:

template <char const*> struct X { };
如何:

template <S> struct Y { };
这种类型具有私有成员,因此强制执行一些不变量,并且可能对“相同”的含义有不同的理解,而不仅仅是“其所有成员都是成对等效的”。实际上,
String
大致就是
std::String
的外观(忽略SSO),如果我们采用memberwise等效的方法,那么我们会遇到以下情况:

template <String> struct Z { };
模板结构Z{};
Z
每次可能给出不同的类型-因为我们必须分配存储来保存字符串,而那些底层指针可能不同。P1907的一个重要驱动因素是希望最终允许:

template <std::string> struct C;
模板结构C;
这样,
C
不仅在一个翻译单元中始终是相同的类型,而且在所有翻译单元中也始终是相同的类型。基于
/
=
的机制在这种情况下不起作用。让
std::string
作为非类型模板参数正常工作的唯一方法是能够有一个自定义机制,其中
std::string
的作者指定等价性基于什么——在这种情况下,我们甚至不看容量指针,它只基于从
开始
结束
的字符序列(不是指针值,而是指向的值)

这种新机制还不存在(作者暗示了一种
操作员模板
),因此在它存在之前,有两种选择:

  • 删除所有类类型作为非类型模板参数
  • 提出一种默认机制,该机制适用于某些类型,但不会向其他类型添加不正确的等价概念,即使这会阻止将某些类类型用作非类型模板参数,而成员等价规则就是正确的

  • 我们选择了选项2,使用“所有公共”作为实现简单、成员对等的机制。。。了解到C++23将有这样一种机制(如
    运算符模板
    ),允许类型为
    std::string
    std::vector
    std::optional
    )的非类型模板参数,等等。

    不再需要默认的
    操作员
    。这不是问题,也不是原因。我没有回答你的问题。只是想指出,NTTP在当前形式下按照C++草稿工作,不需要<代码> <代码>标题,也没有默认的代码>运算符< /代码>。因此,它们在您的测试用例中是不必要的。我编辑了这个例子。“基于/==的机制在这种情况下不起作用。”你能详细解释一下为什么不起作用吗?在我看来,一些假设的
    操作符模板
    函数基本上会像
    constepr操作符==
    那样:测试字符串中的所有字符是否相等。是您有时希望他们做不同的事情,还是这是一个
    constexpr
    问题,还是其他问题?@nicolas:
    操作符模板将以编译器可以理解的格式识别字符,并可以进行链接;用户编写的
    运算符==
    将检查它们,但通常不能用于确定需要包含在标识中的内容。P1097R0表示opartor==的编译时结果可能与运行时结果不同(类型a不一致)。有人能举一个例子说明这种情况吗?我无法想象这种情况。@wimalopaan这篇文章给出了多个例子。@wimalopaan这篇文章给出了以下例子:指向成员类型的指针、浮点类型、引用和带有用户定义运算符==的类型。希望C++23不需要这样做。幸运的是,我们应该有
    constexpr
    函数参数,我希望这实际上消除了对重要类NTTP支持的需要。是否有一篇文章描述了这一点(constexpr函数参数)?。这是为C++20编写的。您在哪里看到与上述问题的关系?“是否有一篇文章描述了这一点(constexpr函数参数)?”“这是C++20的。”否。“您在哪里看到与上述问题的关系?”大多数情况下,我都想要一个复杂类型的NTTP,这是因为我使用模板元编程来做一些我们应该能够用常规函数调用来做的事情。使用
    constexpr
    函数参数,我不再需要使用模板参数将
    constexpr
    表单中的文字类型传递给函数。
    template <String> struct Z { };
    
    template <std::string> struct C;