我在C++中使用模板mixins很多,但我想知道为什么这个技术不再使用.它似乎是最终的重用.这种权力和效率的结合是我真正喜欢C++的原因之一,并且无法看到自己转向JIT语言.
这篇文章:http://www.thinkbottomup.com.au/site/blog/C%20%20_Mixins_-_Reuse_through_inheritance_is_good是一个很好的背景,如果你不知道它们是什么,并在重用方面如此清楚地说明和表现.
我必须链接两个库,比如A和B.一些文件在两个库中都很常见.所以,我在命名空间中声明库A中的函数,比如说abc.因此,在A和B中,函数func如下所示:
[ in A]
namespace abc {
extern "C" void func();
}
[in B]
extern "C" void func();
Run Code Online (Sandbox Code Playgroud)
在构建项目时,编译器抛出链接错误,说明函数func的多个定义.不是命名空间内的A中的函数func,还是extern"C"函数存在一些问题.如果有,那我怎么能区分它们呢?
我有这个脚本可以通过两种方式调用:
MyScript -foo path\to\folder
Run Code Online (Sandbox Code Playgroud)
要么
MyScript -bar path\to\folder
Run Code Online (Sandbox Code Playgroud)
(也就是说,我可以传递一个开关加上一个文件夹或一个字符串参数加上一个文件夹.)
我试图将参数声明放入我的脚本中以反映该语法:
param(
[parameter(Mandatory=$false)] [switch]$foo,
[parameter(Mandatory=$false)] [String]$bar,
[parameter(Mandatory=$true)] [System.IO.FileInfo]$path
)
Run Code Online (Sandbox Code Playgroud)
但是我必须path
明确地传递以调用脚本:
MyScript -l -path path\to\folder
Run Code Online (Sandbox Code Playgroud)
那么(如何)我可以做到这两个bar
和path
位置参数?
注意:如果我选择了一个非常愚蠢的语法来调用脚本,我仍然可以更改它.
这个问题是由于一些混合语言编程而产生的.我有一个我想用C++代码调用的Fortran例程.Fortran通过引用传递其所有参数(除非您另有说明).
所以我认为在我的C++代码中我会聪明(糟糕的开始)并定义类似这样的Fortran例程:
extern "C" void FORTRAN_ROUTINE (unsigned & flag);
Run Code Online (Sandbox Code Playgroud)
这段代码工作了一段时间,但(当然,当我需要离开时)突然开始吹回电话.清除指示一个munged调用堆栈.
一位工程师来到我身后,解决了这一问题,宣布该程序必须在C定义++作为
extern "C" void FORTRAN_ROUTINE (unsigned * flag);
Run Code Online (Sandbox Code Playgroud)
除了两件事,我接受了.一个是编译器不通过引用传递引用参数似乎相当直观,而且我无法在任何地方找到这样的文档.另一个是他同时在那里改变了大量其他代码,所以理论上它可能是另一个修改问题的修改.
所以问题是,C++如何实际传递参考参数?是否可以免费为小值或其他东西进行复制,复制?换句话说,参考参数在混合语言编程中是完全无用的吗?我想知道所以我再也没有犯同样的代码杀戮错误.
在C++中,有什么区别:
void func(MyType&); // declaration
//...
MyType * ptr;
func(*ptr); // compiler doesnt give error
func(ptr); // compiler gives error i thought & represents memory address so
// this statement should correct as ptr is only a pointer
// or address of some real var.
Run Code Online (Sandbox Code Playgroud) 在自动执行某些SVN任务的PowerShell脚本中,我具有以下功能:
function SvnUrlExists($url)
{
svn info $url | out-null 2>&1
return $?
}
Run Code Online (Sandbox Code Playgroud)
由于这显式测试是否存在某个SVN存储库URL,因此我对任何错误输出都不感兴趣.但是,尽管我发现stderr
在PowerShell 2>&1
中重定向的所有内容都建议将其重定向到stdout
,但仍会输出错误消息:
svn: warning: W170000: URL 'blahblah' non-existent in revision 26762 svn: E200009: Could not display info for all targets because some targets don't exist
不幸的是,这严重扰乱了我脚本的输出.
我做错了什么,如何抑制此错误输出?
在下面的代码中,我希望在调用Class构造函数时将数组定义为大小为x的数组.我怎样才能做到这一点?
class Class
{
public:
int array[];
Class(int x) : ??? { }
}
Run Code Online (Sandbox Code Playgroud) 我昨晚无法入睡,开始思考std::swap
.这是熟悉的C++ 98版本:
template <typename T>
void swap(T& a, T& b)
{
T c(a);
a = b;
b = c;
}
Run Code Online (Sandbox Code Playgroud)
如果用户定义的类Foo
使用外部资源,则效率低下.常用的习语是提供一种方法void Foo::swap(Foo& other)
和一种专业化std::swap<Foo>
.请注意,这不适用于类模板,因为您不能部分地专门化函数模板,并且重std
命名命名空间中的名称是非法的.解决方案是在一个人自己的命名空间中编写模板函数,并依赖于参数依赖查找来查找它.这主要取决于客户端遵循" using std::swap
成语"而不是std::swap
直接调用.非常脆弱.
在C++ 0x中,如果Foo
有一个用户定义的移动构造函数和一个移动赋值运算符,提供一个自定义swap
方法和一个特化std::swap<Foo>
几乎没有性能优势,因为C++ 0x版本std::swap
使用高效的移动而不是副本:
#include <utility>
template <typename T>
void swap(T& a, T& b)
{
T c(std::move(a));
a = std::move(b);
b = std::move(c);
}
Run Code Online (Sandbox Code Playgroud)
不必再捣乱swap
已经从程序员那里承担了很多负担.当前的编译器不会自动生成移动构造函数和移动赋值运算符,但据我所知,这将改变.剩下的唯一问题是异常安全,因为一般来说,允许移动操作,这会打开一大堆蠕虫.问题是"移动对象的状态究竟是什么?" 使事情进一步复杂化.
然后我在想,std::swap
如果一切顺利的话,C++ 0x 中的语义究竟是什么?交换之前和之后的对象状态是什么?通常,通过移动操作进行交换不会触及外部资源,只会触及"平面"对象表示本身. …
我们正在使用位于VxWorks 5.5顶层的专有嵌入式平台进行编程.在我们的工具箱中,我们有一个条件变量,它是使用VxWorks二进制信号量实现的.
现在,POSIX提供了一个等待函数,它也需要一个互斥量.这将解锁互斥锁(以便某些其他任务可能写入数据)并等待另一个任务发出信号(完成写入数据).我相信这实现了所谓的监视器,ICBWT.
我们需要这样的等待函数,但实现它很棘手.一个简单的方法就是这样做:
bool condition::wait_for(mutex& mutex) const {
unlocker ul(mutex); // relinquish mutex
return wait(event);
} // ul's dtor grabs mutex again
Run Code Online (Sandbox Code Playgroud)
然而,这是一种竞争条件,因为它允许另一项任务在解锁之后和等待之前抢占这一任务.另一个任务可以写入解锁后的日期,并在此任务开始等待信号量之前发出信号.(我们已经对此进行了测试,确实发生了这种情况并永远阻止了等待任务.)
鉴于VxWorks 5.5似乎没有提供API来等待信号暂时放弃信号量,有没有办法在提供的同步例程之上实现它?
注意: 这是一个非常老的VxWorks版本,在 没有POSIX支持的情况下编译 (由专有硬件的供应商提供,根据我的理解).
考虑一下:
std::string foo();
void bar() {
const std::string& r1 = foo();
static const std::string& r2 = foo();
}
Run Code Online (Sandbox Code Playgroud)
我知道第一次调用产生的字符串的生命周期foo()
将延长到生命周期r1
.
r2
然而,暂时的约束呢?它会一直存在到示波器的末端,还是在bar()
重新进入时仍然存在?
注意:我对特定编译器是否这样做感兴趣.(我对我们使用的那个很感兴趣,我可以轻松地测试它.)我想知道标准对此有何看法.
c++ ×8
powershell ×2
reference ×2
arrays ×1
c++-faq ×1
c++11 ×1
constructor ×1
extern ×1
mixins ×1
namespaces ×1
parameters ×1
performance ×1
pointers ×1
reusability ×1
svn ×1
swap ×1
templates ×1
temporary ×1
vxworks ×1