我只是遇到了一个奇怪的模棱两可的问题,我花了很长时间才将其隔离开来,因为在轻微的API更改后,它突然出现在某些模板混乱的中间。
下面的示例探讨了调用构造函数的不同方法(或者我认为),其中一些方法对我来说是相当模糊的。我试图在所有这些对象中声明一个A
类型的对象。
#include <vector>
#include <cstdlib>
#include <iostream>
#include <typeinfo>
using namespace std;
// just a dummy class to use in the constructor of the next class
struct V {
V(const std::vector<size_t> &){}
};
// the class we are interested in
struct A{
A(const V &){}
A(int, const V &){}
A(const V &, int){}
A(const V &, const V &){}
};
// a dummy function to delegate construction of V
V buildV(std::vector<size_t> &v){ return V(v); }
int main(){
std::vector<size_t> v = {1024,1024};
V vw(v);
// I am using macros to make the constructor argument more visible
#define BUILD_A(X) { A a(X); std::cerr << typeid(a).name() << std::endl; }
#define BUILD_A2(X,Y) { A a(X, Y); std::cerr << typeid(a).name() << std::endl; }
// All of the following call the constructor of A with different parameters
// the comment on the right shows the type of the declared a
/* 1 */ BUILD_A( vw ) // object
/* 2 */ BUILD_A( V(v) ) // function pointer
/* 3 */ BUILD_A( v ) // object
/* 4 */ BUILD_A( std::vector<size_t>() ) // function pointer
/* 5 */ BUILD_A( (V)V(v) ) // object
/* 6 */ BUILD_A( ( V(v) ) ) // object
/* 7 */ BUILD_A( buildV(v) ) // object
/* 8 */ BUILD_A2(10,V(v)) // object
/* 9 */ BUILD_A2(V(v),10) // object
/* 10 */ BUILD_A2(vw,V(v)) // object
/* 11 */ BUILD_A2(V(v), vw) // object
/* 12 */ //BUILD_A2(V(v), V(v)) // doesn't compile
/* 13 */ BUILD_A2(V(v), (V)V(v)) // object
}
第二个和第四个示例似乎声明了一个函数指针而不是一个对象,这引发了两个问题:
V(v)
解释为A a(V(v))
的类型而不是对象? V(v)
投射回(V)V(v)
的解释不同? ((...))
是否在那里具有语义含义,还是只是有助于消除解析器的歧义?我不知道这怎么可能是一个优先问题。 V(v)
评估为类型而不是对象,为什么A a(V(v), V(v))
在12中不合法? 谢谢,
最佳答案
这被称为最令人讨厌的解析:尝试的声明被解析为函数声明。
C++规则是,如果可以将某些内容解析为函数声明,那么它将是。
有一些解决方法,例如编写A a(( V(v) ))
,不能将其解析为带有a
参数的函数V
的声明并返回A
。
关于警告,该标准不需要对此进行任何诊断。毕竟,潜在的歧义已经得到解决。赞成功能。 :-)
关于c++ - 作为构造函数参数的构造函数调用将声明评估为函数指针,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15956326/