考虑这个简单而毫无意义的代码.
#include <iostream>
struct A {
template<int N>
void test() {
std::cout << N << std::endl;
}
};
int main() {
A a;
a.test<1>();
}
Run Code Online (Sandbox Code Playgroud)
这是一个非常简单的函数模板示例.但是,如果我想A::test用重载代替operator()它以使它成为一个算符呢?
#include <iostream>
struct A {
template<int N>
void operator()() {
std::cout << N << std::endl;
}
};
int main() {
A a;
a<1>(); // <-- error, how do I do this?
}
Run Code Online (Sandbox Code Playgroud)
当然,如果采用operator()依赖于模板的参数,编译器可能会推导出模板.但我无法弄清楚使用无参数仿函数指定模板参数的正确语法.
有没有正确的方法来做到这一点?
显然,这个代码可以工作,因为它绕过了仿函数语法:
a.operator()<1>();
Run Code Online (Sandbox Code Playgroud)
但这有点打败了它作为仿函数的目的:-P.
我使用一个众所周知的模板来允许二进制常量
template< unsigned long long N >
struct binary
{
enum { value = (N % 10) + 2 * binary< N / 10 > :: value } ;
};
template<>
struct binary< 0 >
{
enum { value = 0 } ;
};
Run Code Online (Sandbox Code Playgroud)
所以你可以做二进制<101011011> :: value.不幸的是,对于无符号长整数,它有20位数的限制.
有没有人有更好的解决方案?
我喜欢使用智能指针,并且已经看到了一些代码,这些代码很好地利用了typedefs make使它们变得更漂亮.例如:
struct A {
typedef boost::shared_ptr<A> pointer;
};
Run Code Online (Sandbox Code Playgroud)
允许我写: A::pointer a(new A);
但是我在typedef幸福中遇到了一个小问题: - /,前言声明......
想象一下这种情况:
struct B;
struct A {
boost::shared_ptr<B> b_;
};
struct B {
boost::shared_ptr<A> a_;
};
Run Code Online (Sandbox Code Playgroud)
效果很好,但我想清理一下.不幸的是,这是行不通的
struct B;
struct A {
typedef boost::shared_ptr<A> pointer;
B::pointer b_; // <-- error here
};
struct B {
typedef boost::shared_ptr<B> pointer;
A::pointer a_;
};
Run Code Online (Sandbox Code Playgroud)
我理解为什么,在文件中的那一点,编译器没有信息,实际上B中有一个名为的类型pointer.
我有一种感觉,我至少在某些方面坚持使用旧方法,但我很想听到一些聪明的想法.
所以我的应用程序主要基于使用QPlugin系统的QT API.它使用起来相当简单,你定义了一个从接口继承的类,当加载插件时,你得到一个该类的实例.最后,它将归结为dlopen/ dlsym或LoadLibrary/ GetProcAddress,适用于操作系统的任何内容.我没有问题,一切都按预期工作.
所以,关于这个问题.有许多功能涉及插件需要引用主应用程序提供的数据/功能.例如,我的应用程序有一个GUI,所以我在我的应用程序中有一个" plugin::v1::gui"函数返回一个QWidget *.如果我想要一个插件能够将内容添加到我的UI中,或者甚至让它的对话框成为我的UI的子对象,它将需要一个指向它的指针.
我在Linux上开始开发并很快遇到这样一个事实:默认情况下,加载器不会在加载它的应用程序中填充共享对象中未解析的符号.没问题,容易解决.-rdynamic在我的旗帜上添加" "并继续前进.工作得很好.
现在我发现在Windows上似乎没有相应的东西:(.那么什么是一个好的解决方案?
到目前为止,我提出的最好的方法是在我的主应用程序中填充一个结构,该结构包含指向插件可能关心的每个对象/函数的指针.然后将它传递给插件的" init()"函数,现在它有适当的指针指向所有内容,但这是一个烦人的解决方案,因为现在我必须在多个地方进行更改,每当我添加一些东西.
有更好的解决方案吗?SO社区如何处理这个问题?
所以我在开发中使用Qt并且非常喜欢它.Qt对象的通常设计模式是使用它们来分配它们new.
几乎所有示例(尤其是Qt设计器生成的代码)都不会检查std::bad_alloc异常.由于分配的对象(通常是小部件等)很小,因此这几乎不成问题.毕竟,如果你没有分配20个字节之类的东西,那么你可以做的事情并不多,无法解决问题.
目前,我采用了一种策略,即在try/catch中包装"large"(大小超过一页或两页)分配.如果失败了,我会向用户显示一条消息,几乎任何更小的消息,我只会让应用程序崩溃并出现std::bad_alloc异常.
所以,我想知道这方面的思想是什么?
检查每一项new操作是否是好政策?或者只有我希望有可能失败的?
此外,在处理资源可能受到更多限制的嵌入式环境时,这显然是一个完全不同的故事.我在桌面应用程序的上下文中询问,但也会对涉及其他场景的答案感兴趣.
我只是想,如果我要实现std::inplace_merge它可能看起来像这样:
template <class Bi, class Cmp>
void inplace_merge(Bi first, Bi middle, Bi last, Cmp cmp) {
if(first != last) {
typedef typename iterator_traits<Bi>::value_type T;
typedef typename iterator_traits<Bi>::difference_type Dist;
const Dist count = distance(first, last);
if(count != 1) {
// can I avoid this allocation?
T *const temp = new T[count];
merge(first, middle, middle, last, temp, cmp);
copy(temp, temp + count, first);
delete [] temp;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我知道我可以使用现有的实现,但除了重点之外.如果有比我所知的更好的算法,我只是好奇.
我想到这一点的原因是大多数c ++标准库(如果我没记错的话,所有的STL)都允许用户指定执行分配的方式和位置,但如果std::inplace_merge需要按设计分配,似乎没有办法如果这是一个问题,控制它.
我认为答案的一个暗示来自于标准本身的复杂性std::inplace_merge:
复杂性:当有足够的额外内存可用时,(最后 - …
我遇到过一些我认为应该编译的代码,但是没有.所以我希望SO的一些当地标准专家可以提供帮助:-).
我基本上有一些类似于这样的代码:
#include <iostream>
template <class T = int>
class A {
public:
class U {
};
public:
U f() const { return U(); }
};
// test either the work around or the code I want...
#ifndef USE_FIX
template <class T>
bool operator==(const typename A<T>::U &x, int y) {
return true;
}
#else
typedef A<int> AI;
bool operator==(const AI::U &x, int y) {
return true;
}
#endif
int main() {
A<int> a;
std::cout << (a.f() == 1) …Run Code Online (Sandbox Code Playgroud) 这是一个相关的问题,但我无法弄清楚如何应用mechanize/urllib2的答案:如何强制python httplib库只使用A请求
基本上,给出这个简单的代码:
#!/usr/bin/python
import urllib2
print urllib2.urlopen('http://python.org/').read(100)
Run Code Online (Sandbox Code Playgroud)
这导致wireshark说以下内容:
0.000000 10.102.0.79 -> 8.8.8.8 DNS Standard query A python.org
0.000023 10.102.0.79 -> 8.8.8.8 DNS Standard query AAAA python.org
0.005369 8.8.8.8 -> 10.102.0.79 DNS Standard query response A 82.94.164.162
5.004494 10.102.0.79 -> 8.8.8.8 DNS Standard query A python.org
5.010540 8.8.8.8 -> 10.102.0.79 DNS Standard query response A 82.94.164.162
5.010599 10.102.0.79 -> 8.8.8.8 DNS Standard query AAAA python.org
5.015832 8.8.8.8 -> 10.102.0.79 DNS Standard query response AAAA 2001:888:2000:d::a2
Run Code Online (Sandbox Code Playgroud)
这是一个5秒的延迟!
我的系统中没有启用IPv6(gentoo编译 …
对于个人项目,我一直在实现自己的libstdc ++.一点一滴,我一直在取得一些不错的进展.通常,我将使用http://www.cplusplus.com/reference/中的示例来获取一些基本测试用例,以确保我有明显的功能按预期工作.
今天我遇到了一个问题std::basic_string::replace,特别是基于迭代器的版本,使用从网站上复制的逐字逐句(http://www.cplusplus.com/reference/string/string/replace/)(我添加了评论到指出有问题的线条):
// replacing in a string
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string base="this is a test string.";
string str2="n example";
string str3="sample phrase";
string str4="useful.";
// function versions used in the same order as described above:
// Using positions: 0123456789*123456789*12345
string str=base; // "this is a test string."
str.replace(9,5,str2); // "this is an example string."
str.replace(19,6,str3,7,6); // "this is an example phrase."
str.replace(8,10,"just all",6); …Run Code Online (Sandbox Code Playgroud) 因此,在一位同事的建议下,我刚刚测试了三元运算符和等效的If-Else块之间的速度差异......似乎三元运算符产生的代码比If-Else快1到2倍.我的代码是:
gettimeofday(&tv3, 0);
for(i = 0; i < N; i++)
{
a = i & 1;
if(a) a = b; else a = c;
}
gettimeofday(&tv4, 0);
gettimeofday(&tv1, 0);
for(i = 0; i < N; i++)
{
a = i & 1;
a = a ? b : c;
}
gettimeofday(&tv2, 0);
Run Code Online (Sandbox Code Playgroud)
(抱歉使用gettimeofday而不是clock_gettime ......我会尽力改善自己.)
我尝试改变我对块进行计时的顺序,但结果似乎仍然存在.是什么赋予了?此外,If-Else在执行速度方面表现出更多的可变性.我应该检查gcc生成的程序集吗?
顺便说一句,这都是在优化级别零(-O0).
我是在想象这个,还是有些东西我没有考虑到,或者这是机器相关的东西,还是什么?任何帮助表示赞赏.