Bjarne Stroustrup最近发表了一篇关于C++ Concepts 的报告,他提到了一些让我感到惊讶的事情.示例(在第7.1节中)使用"简写模板表示法",基本上是这样的:
void foo1(auto x,auto y); // x and y may have different types (1)
void foo2(SomeConcept x,SomeConcept y); // x and y must have the same type (2)
Run Code Online (Sandbox Code Playgroud)
就我个人而言,这似乎非常违反直觉; 事实上,我希望foo2接受不同类型的值x,y,只要各个类型满足SomeConcept.请注意,程序员始终可以通过编写以下内容之一来明确指定其意图:
template <SomeConcept T> void foo2(T x, T y); // (3)
template <SomeConcept T1,SomeConcept T2> void foo2(T1 x,T2 y); // (4)
Run Code Online (Sandbox Code Playgroud)
直觉上,我希望(2)中的简写符号等同于(4),因此更符合无约束模板(1)的含义.有人可以解释这个问题并解释这个设计决定背后的理由吗?
一些评论:
我在C++中遇到了隐式转换的问题.以下是一个最小的例子:
struct A {
virtual void f()=0; // abstract
};
struct Ad : A {
virtual void f() {} // not abstract
};
struct B {
operator Ad () const { return Ad(); }
};
void test(A const &lhs) {}
int main()
{
B b;
test(b);
}
Run Code Online (Sandbox Code Playgroud)
我希望编译器做的是:将b转换为Ad类型的变量(使用B中定义的转换)并将结果传递给test.但是,上面的代码不能在GCC中编译(启用C++ 11),结果是无法分配抽象类型"A"的对象.
有些事情需要注意:
f()=0;来使非抽象f() {},代码工作得很好.在类似的问题(例如,此处)中已经指出,您不能将类方法指针作为谓词传递std::all_of。
但是,对于C ++ 17,我们有std::invoke,这应该使std::all_of相似的函数更容易接受成员函数(甚至成员变量)指针。
更具体地说,以下内容无法在GCC 9.2上编译:
#include <algorithm>
#include <vector>
struct S {
bool check() const { return true; }
};
int main() {
std::vector<S> vs;
std::all_of(vs.begin(), vs.end(), &S::check);
}
Run Code Online (Sandbox Code Playgroud)
该Godbolt链接包含一些示例代码和all_of使用invoke 的玩具版本。
为什么有这个限制?我想念什么吗?我以为当std::invoke标准化时,它也应该应用于适当的STL函数。