使用概念的C++别名模板(typedef)?

4

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4553.pdf

的英文句子翻译为中文是:

gcc6: -fconcepts

翻译后的意思是:gcc6:-fconcepts
template<typename T>
concept bool String = requires(T s)
{
    { s.clear() } -> void;
    // etc.
};

void print(const String& message);
//void print(Str message); // I want Str = const String&

void test()
{
  std::string str;
  print(str);
}

有没有一种方法可以将Str声明为const String&

6
也许这是可能的,但我不建议隐藏那样的事情。如果我看到一个类型为“Str”的参数,我会认为它创建了一个副本,而不是秘密地取引用。 - TartanLlama
这段代码只是一个例子。我想知道它是否可行,而不是这个特定的例子是否有意义。 - Boris Rasin
3
您可以这样做:template <String T> using Str = const T&;,但是这种方式无法进行类型推导。 - TartanLlama
这没有意义。它不允许声明缩写模板 "void print(Str message);",正如所请求的那样。 - Boris Rasin
这就是为什么我说你不能用那种方法获得推导。你需要模板推导来执行对const T&的模式匹配。 - TartanLlama
我会说,唯一的方法是 #define Str const String& - metalfox
1个回答

2
有没有办法将Str声明为const String&
没有。而且,你也不想这样做。概念是关于向类型添加约束的。因此,如果你想将print限制为接受符合String模型的东西,你可以这样做:
template <typename T> requires String<T> void print(T const&); // requires-clause
template <String T> void print(T const&); // partial-concept-id
void print(String auto const&); // probably what C++20 will allow

但约束和值的类型是正交的。您可以按值获取String

void print(String auto);

您可以通过转发引用获取String

void print(String auto&&);

这些都是与“我想要一个字符串”方面不同的选项。你不能真正将它们分组在一起。


你最好能做到的是:

template <String T> using Str = T const&;
template <typename T> void print(Str<T>); // silently a const&

或者

template <typename T> using CR = T const&;
template <String T> void print(CR<T>); // silently a const&

那样做是可以的。对于“可以”的定义而言。但是……不要那样做。函数采用const&而非值这一事实是非常重要的视觉信息,不要隐藏它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接