什么是关于什么参数依赖查找的好解释?很多人也称它为Koenig Lookup.
我最好知道:
C++规范的哪一部分限制参数依赖查找在相关命名空间集合中查找函数模板?换句话说,为什么main
下面的最后一次调用无法编译?
namespace ns {
struct foo {};
template<int i> void frob(foo const&) {}
void non_template(foo const&) {}
}
int main() {
ns::foo f;
non_template(f); // This is fine.
frob<0>(f); // This is not.
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试定义基类,它只包含typedef.
template<typename T>
class A
{
public:
typedef std::vector<T> Vec_t;
};
template<typename T>
class B : public A<T>
{
private:
Vec_t v; // fails - Vec_t is not recognized
};
Run Code Online (Sandbox Code Playgroud)
BI中为什么会收到Vec_t无法识别的错误,我需要明确写出来?
typename A<T>::Vec_t v;
Run Code Online (Sandbox Code Playgroud) 这个问题是一个在问的赞助这个线程.
使用以下类定义:
template <class T>
class Foo {
public:
Foo (const foo_arg_t foo_arg) : _foo_arg(foo_arg)
{
/* do something for foo */
}
T Foo_T; // either a TypeA or a TypeB - TBD
foo_arg_t _foo_arg;
};
template <class T>
class Bar : public Foo<T> {
public:
Bar (const foo_arg_t bar_arg, const a_arg_t a_arg)
: Foo<T>(bar_arg) // base-class initializer
{
Foo<T>::Foo_T = T(a_arg);
}
Bar (const foo_arg_t bar_arg, const b_arg_t b_arg)
: Foo<T>(bar_arg)
{
Foo<T>::Foo_T = T(b_arg);
} …
Run Code Online (Sandbox Code Playgroud) 下面的代码片段编译(演示):
struct A{ int i = 10; };
int main() {
struct A{ int i = 20; };
struct A;
struct A a;
}
Run Code Online (Sandbox Code Playgroud)
但这不是:
struct A{ int i = 10; };
int main() {
// struct A{ int i = 20; };
struct A;
struct A a;
}
Run Code Online (Sandbox Code Playgroud)
我可以看到答案可能是标准中的这些段落:
[basic.lookup.elab]/2和[basic.scope.pdecl]/7.
但我真的不知道如何从这两段中推断出上面显示的不同行为.
需要注意的是在第一个例子中,struct A
是不是第一次在声明阐述类型说明符 struct A;
,但在定义struct A
中main()
.
在第二个例子中,struct A
也未先在声明阐述型说明符 struct …
在类中定义的友元函数的完全限定名称是什么?
我最近看到了一个类似于以下的例子.以下完全限定名称是val()
什么?
#include <iostream>
namespace foo {
class A {
int x;
public:
A(int x = 0) : x(x) { }
friend int val(const A &a) { return a.x; }
};
}
int main() {
foo::A a(42);
// val() found using ADL:
std::cout << val(a) << std::endl;
// foo::val(a); // error: 'val' is not a member of 'foo'
// foo::A::val(a); // error: 'val' is not a member of 'foo::A'
return 0;
}
Run Code Online (Sandbox Code Playgroud)
参数依赖查找是唯一val()
可以找到的方法吗?
不可否认,这并非源于实际问题.我只是希望获得更好的理解.
请考虑以下代码段:
struct Base { };
struct Derived : Base { };
void f(Base &) { std::cout << "f(Base&)\n"; }
template <class T = int>
void g() {
Derived d;
f(T{} ? d : d); // 1
}
void f(Derived &) { std::cout << "f(Derived&)\n"; }
int main() {
g();
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我认为应该在第一阶段查找对f
at 的函数调用// 1
,因为它的参数的类型是明确的Derived&
,因此可以解析为f(Base&)
范围中唯一的一个.
Clang 3.8.0同意我的观点,但是GCC 6.1.0没有,并推迟f
到第二阶段的查找,在那里f(Derived&)
被选中.
哪个编译器是对的?
当我调查Qt的源代码时,我发现trolltech的人明确使用this
关键字来访问析构函数中的字段.
inline ~QScopedPointer()
{
T *oldD = this->d;
Cleanup::cleanup(oldD);
this->d = 0;
}
Run Code Online (Sandbox Code Playgroud)
那么,这个用法有什么意义呢?有什么好处吗?
编辑:对于那些投票支持关闭此问题的人,我怀疑这种用法适用于某些类继承案例
QScopedPointer类定义的一部分:
template <typename T, typename Cleanup = QScopedPointerDeleter<T> >
class QScopedPointer
Run Code Online (Sandbox Code Playgroud) 以下代码不使用gcc编译,但使用Visual Studio编译:
template <typename T> class A {
public:
T foo;
};
template <typename T> class B: public A <T> {
public:
void bar() { cout << foo << endl; }
};
Run Code Online (Sandbox Code Playgroud)
我收到错误:
test.cpp:在成员函数'void B :: bar()'中:
test.cpp:11:错误:在此范围内未声明'foo'
但它应该是!如果我换bar
到
void bar() { cout << this->foo << endl; }
Run Code Online (Sandbox Code Playgroud)
然后它确实编译,但我不认为我必须这样做.GCC在这里遵循C++官方规范中的某些内容,还是仅仅是一个怪癖?
当编译器尝试解析i.template hi<T>();
它时hi
,在全局命名空间中找到而不是hi
在i
(ideone)上找到方法.为什么?
#include <cstdio>
// Define 'hi' and 'bye' in the global namespace; these should *not* be used
template<typename T> struct hi { };
template<typename T> struct bye { };
// Foo needs to be templated for Foo::Inner to be a dependent type (I think)
template<typename T>
struct Foo
{
struct Inner {
// This is a plain-old templated member function of Inner, yes?
template<typename U>
void hi() { std::printf("hi!\n"); …
Run Code Online (Sandbox Code Playgroud) c++ ×10
name-lookup ×10
templates ×5
inheritance ×2
base-class ×1
c++-faq ×1
c++11 ×1
compiler-bug ×1
declaration ×1
definition ×1
friend ×1
gcc ×1
namespaces ×1
qt ×1
scope ×1
this ×1
typedef ×1