我想要一个带有单个参数的构造函数,并且仅当该参数的类型::t具有必须是某个其他类型的子类型的成员类型时才启用.我正在使用类型特征,代码如下所示:
#include <type_traits>
struct Y{};
struct X{
//Only allow if T has a type member T::t which is a subtype of Y
template <typename T>
X(T* t, std::enable_if<std::is_base_of<Y, typename T::t>::value, int>::type e = 0){}
};
Run Code Online (Sandbox Code Playgroud)
但是,g ++抱怨如下:
test/test.cpp:8:75: error: ‘std::enable_if<std::is_base_of<Y, typename T::t>::value, int>::type’ is not a type
Run Code Online (Sandbox Code Playgroud)
我做错了什么?
在PHP中是否可以访问一个对象的成员,其中成员的名称由类常量指定?
考虑这个例子:
class X{
const foo = "abc";
}
class Y{
public $abc;
}
$y = new Y();
$y->X::foo = 23; //This does not work
Run Code Online (Sandbox Code Playgroud)
解析器不接受最后一行,但这就是我想要的.我想访问存储在类常量中的名称的字段X::foo.是否有语法来实现这一目标?
模板类的每个实例都会复制所有静态成员。如果我想要一个对于所有实例仅存在一次的静态成员,我该怎么办?在类模板之外使用普通的静态字段?可以,但看起来不优雅,因为与模板类不再有关联。有没有办法以某种方式将这种独特的静态成员与模板类相关联?
假设我有一个带有方法模板的类:
//file: X.h
class X{
int x;
//... more members and non-template functions
template<typename T>
void foo(T t){ //Error, cannot define the method here. Declaration is okay
Y y = ...;
}
}
//file Y.h
class Y {
X x;
}
Run Code Online (Sandbox Code Playgroud)
由于循环类依赖(foo的主体依赖于Y和Y依赖于X),我无法定义foo我声明它的方法模板(请不要现在质疑设计).
那么,foo在这种情况下把定义放在哪里?我无法将其他定义放入.cpp文件中,否则链接将失败.
我的解决方案是创建一个新的头文件,例如"X.hpp",只添加模板方法的定义.在这个文件中,我包含"Xh"和"Yh".现在,每当我需要X类时,我只需要包含"X.hpp",它将包含其他必要的h文件.
所以我的问题是:这是正确/最好的方法吗?它以某种方式让我觉得我只有一个单独的方法模板定义的.hpp文件,但它似乎是圆形类型依赖的唯一可行方法.请再次:不要质疑设计,说"最好避免循环类型依赖"或类似的东西.问题是:如果我有这些依赖关系,那么处理单个方法模板的最佳方法是什么.
我得到了以下代码(不要争论它是否有意义,它只是一个最小的例子):
struct X{
template <typename T>
T foo(){ return T(); }
};
template <typename T>
struct Z{
virtual X bar(){
bar().foo<int>();
return X();
}
};
Run Code Online (Sandbox Code Playgroud)
它不能在我的g ++ 4.6.3上编译.该行bar().foo<int>();给出以下错误:
error: expected primary-expression before ‘int’
error: expected ‘;’ before ‘int’
Run Code Online (Sandbox Code Playgroud)
当我第一次将bar()的结果保存在局部变量中时,它就可以工作,即如果我替换bar().foo<int>()为
X x = bar();
x.foo<int>();
Run Code Online (Sandbox Code Playgroud)
然后它工作.如果我现在声明局部变量auto而不是X,即:
auto x = bar();
x.foo<int>();
Run Code Online (Sandbox Code Playgroud)
然后我收到和以前一样的错误.如果我从类Z中删除type参数(即使它成为常用而不是模板类),那么它再次起作用.
如果我使用classtype X而不是intfoo的类型参数,即foo<X>,我收到以下错误:
expected primary-expression before ‘>’ token
expected primary-expression before ‘)’ token
Run Code Online (Sandbox Code Playgroud)
我真的无法在这里发现错误.请帮忙!
由于在其他线程中完成了基准测试(参见/sf/answers/27833221/),因此可以看出Java 6中的instanceof实际上非常快.这是如何实现的?
我知道对于单继承,最快的想法是使用一些嵌套间隔编码,其中每个类维持[低,高]间隔,而instanceof只是间隔包含测试,即2个整数比较.但它是如何制作接口的(因为区间包含仅适用于单继承)?如何处理类加载?加载新的子类意味着必须调整很多间隔.
在确定任务的最佳数据结构时,有三种考虑因素:
第一个考虑因素可以通过检查数据结构的接口找到,第二个只能在基准测量中测量.但是,如果数据结构只提供一种计算当前使用的内存的方法,则第三种方法非常简单.
STL数据结构不是这种方法.但为什么?对STL中的所有数据结构实现这样的方法将非常简单.对于我作为客户端,编写这样的方法非常困难,因为我必须熟悉内部实现.此外,实现隐藏在私有成员后面,所以我根本无法访问它们.
那他们为什么被排除在外呢?现在,在选择数据结构时,许多其他实现(如当前发布的谷歌btree实现)确实提供了这些方法.比较这些数据结构很容易.但是,当询问STL数据结构在内存消耗方面的表现时,我基本上可以做的就是猜测.
我找不到任何理由,为什么省略这些方法可能是一个设计决定.此外,C++是一种针对高性能和低内存占用而调整的语言.特别是在这种语言中,我认为评估数据结构的内存消耗是一个很常见的用例.所以我也不能认为他们被排除在外因为没有人会使用它们.另外,STL也是一个非常成熟的库,所以原因也不应该是库不够详细.那么省略这些方法的原因可能是什么?
C++的STL的基本迭代器模型基本上包括"给我当前位置的项目"操作符*,"转到下一项"操作符++和用于检查(大多数时间)结束的谓词==/ !=迭代器.当然,还有各种随机访问的迭代器,但最基本的迭代器看起来如上所述.
相比之下,Java有next()和hasNext().接下来大致相当于使用++然后*.hasNext()就像比较结束一样.为什么Java没有采用C++模型(当然,它没有运算符重载所以它必须通过函数来模仿它)?特别是,为什么与方法的结束迭代器进行比较hasNext()?我觉得它往往很难用Java编写的迭代器比C++,因为背后的逻辑next()和hasNext()往往比一个在C++运算符更加复杂.
我试着编写一个"inline-vector"类来方便地在堆栈中存储大量元素:
template<typename T, size_t size_ = 256>
struct InlineVector{
T content[size_];
size_t num;
T() : num(0) {}
~T() { for(size_t s = 0; s < num; s++){ content[s]->~T(); } }
template<typename _Up, typename... _Args>
void emplace_back(_Args&&... __args) { new (&content[num++]) T(__args); }
T& get(size_t i) { assert(i < num); return content[i]; }
}
Run Code Online (Sandbox Code Playgroud)
出于效率原因,我希望content在X构造函数中没有初始化,即使T只有一个非平凡的构造函数.如您所见,内容将在以后实际插入,并在实际插入时添加新内容.但是,C++似乎强制要求content必须在初始化时初始化所有元素X.例如,这不编译:
struct Y{ Y(int){} }
X<Y> foo; // compile error, no constructor for Y is called in …Run Code Online (Sandbox Code Playgroud) 请考虑以下代码
class X{
public:
virtual void foo(X x){ }
virtual void foo(int index){ }
};
class Y : public X{
public:
void foo(int index){ }
};
int main(){
Y y;
y.foo(X()); //Error, see below
}
Run Code Online (Sandbox Code Playgroud)
类X已经重载了虚foo方法.一个版本需要一个版本,另一个版本X需要一个int.现在,类Y继承X并覆盖该方法foo(int).该方法foo(X)不能被覆盖,它应该保持不变.
但是,Y在main方法和调用中创建类型的对象时foo(X),编译器会抱怨以下内容:
In function ‘int main()’:
error: no matching function for call to ‘Y::foo(X)’
note: candidate is:
note: virtual void Y::foo(int)
note: no …Run Code Online (Sandbox Code Playgroud) c++ ×8
java ×2
templates ×2
arrays ×1
constructor ×1
enable-if ×1
include ×1
instanceof ×1
iterator ×1
jvm ×1
overloading ×1
overriding ×1
php ×1
sfinae ×1
stl ×1
syntax-error ×1
type-traits ×1