我正在尝试重构我的代码,以便我使用前向声明而不是包含大量的标头.我是新手,对boost :: shared_ptr有疑问.
说我有以下界面:
#ifndef I_STARTER_H_
#define I_STARTER_H_
#include <boost/shared_ptr.hpp>
class IStarter
{
public:
virtual ~IStarter() {};
virtual operator()() = 0;
};
typedef boost::shared_ptr<IStarter> IStarterPtr;
#endif
Run Code Online (Sandbox Code Playgroud)
然后我在另一个类中有一个函数,它将一个IStarterPtr对象作为参数,比如说:
virtual void addStarter(IStarterPtr starter)
{
_starter = starter;
}
...
IStarterPtr _starter;
Run Code Online (Sandbox Code Playgroud)
如何在不包含IStarter.h的情况下转发声明IStarterPtr?
我正在使用C++ 98,如果这是相关的.
在C++ 11中,要确定某个类是否具有成员函数size,您可以定义以下测试助手:
template <typename T>
struct has_size_fn
{
typedef char (& yes)[1];
typedef char (& no)[2];
template <typename C> static yes check(decltype(&C::size));
template <typename> static no check(...);
static bool const value = sizeof(check<T>(0)) == sizeof(yes);
};
Run Code Online (Sandbox Code Playgroud)
是否有类似的技巧在C++ 98中执行此操作而不依赖于编译器扩展,例如typeof?
假设给出了以下代码.
class A
{
public:
virtual void someMethod()
{
std::cout << "class A" << std::endl;
}
};
class B : public A
{
public:
...
virtual void someMethod() = 0;
...
};
Run Code Online (Sandbox Code Playgroud)
类使用纯 -virtual方法B覆盖someMethod虚方法.这样做的目的可能是在我们的case类中不允许修改的现有类的扩展,但仍然有一个抽象类,它必须是一些其他类的基类.AB
根据MISRA-C++规则10-3-3:代码分析器发出警告:纯虚函数会覆盖非纯虚函数.
但我找不到有关警告的更多细节.上述代码的副作用是什么?这里有什么不好的做法?
更新:标准是MISRA-C++(C++ 98)
据推测,除非使用模板类,否则不应对其进行实例化.然而,这个示例似乎实例化了do_something成员和enable_if失败(如果我们实例化它会是预期的 - 但是AFAIK我们没有实例化).
我错过了一些非常基本的东西吗?
#include <string>
#include <boost/utility.hpp>
struct some_policy {
typedef boost::integral_constant<bool, false> condition;
};
struct other_policy {
typedef boost::integral_constant<bool, true> condition;
};
template <typename policy>
class test {
void do_something(typename boost::enable_if<typename policy::condition>::type* = 0) {}
};
int main() {
test<other_policy> p1;
test<some_policy> p2;
}
Run Code Online (Sandbox Code Playgroud)
我目前有一个项目,我使用最新的编译器(即默认值)在Visual Studio 2015中编程.不幸的是,我要求我的项目在C++ 98环境中编译和执行 - 有没有办法让我在Visual Studio中通过某种方式更改编译器版本来执行此操作,以便我可以检查我的项目是否仍然有效?
此外,在这个项目中我使用FLTK 1.3.3(一个GUI包) - 如果我确实可以在Visual Studio 2015中执行此操作,我是否需要使用C++ 98模式重建此库?
我有一个共享库,导出一元函数,如:
extern "C" void foo(int);
extern "C" void zoo(double);
Run Code Online (Sandbox Code Playgroud)
该库由没有C++ 11支持的编译器使用.我想从函数名称中在结构中静态推断函数类型.
我可以写:
template <typename T, void(*)(T)> struct A{ typedef T arg_t; };
Run Code Online (Sandbox Code Playgroud)
为此,我必须T在实例化模板时明确指定类型,即我必须编写
A<int, &foo>
Run Code Online (Sandbox Code Playgroud)
而不仅仅是
A<&foo>
Run Code Online (Sandbox Code Playgroud)
鉴于此信息嵌入在指针类型中,有没有一种方法可以静态提取?
所以我知道在C++常量中,默认情况下获得的变量与变量不同.这就是我不能放的原因
int foo;
Run Code Online (Sandbox Code Playgroud)
在一些标题中 - 链接器会正确地抱怨多个定义.OTOH,我可以写
const int bar = 42;
Run Code Online (Sandbox Code Playgroud)
在标题中,编译器确保只有一个定义bar.
使用积分常量,很容易看出编译器如何处理这个 - 至少只要没有人获取地址bar或做一些其他有趣的事情,需要它为它分配存储).但是,如果有人怎么办?如果它不是一个整体但需要在运行时执行的代码呢?假设我将其放入标题中:
const std::string baz = "h2g2";
Run Code Online (Sandbox Code Playgroud)
假设没有小的字符串优化,这需要在运行时分配动态内存,因此需要执行代码,地址需要存储在某处,等等.
我假设我最终会得到baz每个翻译单元的一个定义,只是编译器为其分配内部链接以防止链接器抱怨?或者我错过了什么?
注意:我对constexpr普通的旧C++常量不感兴趣,因为它们自80年代以来就存在并且在C++ 98中编纂.(但是,如果一个全面的答案将包括这一切如何融合在一起constexpr,我不会抱怨.)
我们假设有一个template班级Foo:
template <typename T>
class Foo {
void foo();
};
Run Code Online (Sandbox Code Playgroud)
我有另一个template类Bar(独立于第一个类):
template <int N>
class Bar {};
Run Code Online (Sandbox Code Playgroud)
让我们说,我想专门foo()为任何Bar类的方法.我写错了:
template <>
template <int N>
void Foo<Bar<N> >::foo() { /* ... */ }
Run Code Online (Sandbox Code Playgroud)
编译器指责我,因为类型不完整:
error: invalid use of incomplete type 'class Foo<Bar<N> >'
void Foo<Bar<N> >::foo() { }
Run Code Online (Sandbox Code Playgroud)
我正在使用C++ 98,但我想知道C++ 11中是否存在不同的解决方案.
我可以解决专门Foo针对泛型的整个类的问题Bar,但是在我必须定义所有方法之后.
这不是我想要的,我正在寻找(如果存在)更优雅的解决方案(包括C++ 98和C++ 11),它允许我专门化并实现单个类方法.
关于SO的问题没有解释如何专注于模板参数.实际上,我的问题显示了编译器如何抱怨这一点.
我偶然发现了一些非常古老的代码,它有一个带有定义的复制赋值运算符的类,它将其参数作为const引用,但也不检查自赋值,所以基本上:
struct A
{
int q;
A(): q(3) {}
A& operator=(const A& a)
{
q = a.q;
return *this;
}
};
Run Code Online (Sandbox Code Playgroud)
当一个实例A被赋给自己时,这个赋值运算符的行为是什么?我认为这会导致问题,因为它"破坏"参数的常量,任何编译器都可以假设参数没有改变并基于此进行优化.
然而,clang和gcc都没有发出警告,程序运行正常.如果我q在赋值运算符中赋值之前显式将值更改为4,这也可以工作.
c++ ×10
c++98 ×10
templates ×2
c++11 ×1
constants ×1
fltk ×1
inheritance ×1
linkage ×1
mingw ×1
misra ×1
polymorphism ×1
portability ×1
sfinae ×1
shared-ptr ×1