假设我想编写一个泛型函数void f<T>(),如果T是POD类型则执行一项操作,如果T是非POD(或任何其他任意谓词)则执行另一项操作.
实现此目的的一种方法是使用标签库调用模式,如标准库与迭代器类别一样:
template <bool> struct podness {};
typedef podness<true> pod_tag;
typedef podness<false> non_pod_tag;
template <typename T> void f2(T, pod_tag) { /* POD */ }
template <typename T> void f2(T, non_pod_tag) { /* non-POD */ }
template <typename T>
void f(T x)
{
// Dispatch to f2 based on tag.
f2(x, podness<std::is_pod<T>::value>());
}
Run Code Online (Sandbox Code Playgroud)
另一种方法是使用部分专用类型的静态成员函数:
template <typename T, bool> struct f2;
template <typename T>
struct f2<T, true> { static void f(T) { /* POD */ …Run Code Online (Sandbox Code Playgroud) c++ metaprogramming partial-specialization generic-programming
从本质上讲,我希望自动像功能的建立std::make_pair,std::bind1st并且std::mem_fun,使不必编写为每个模板类类型不同的功能,你可以编写处理所有情况下,一旦一个可变参数模板模板功能.这个函数的用法如下:
make<std::pair>(1, 2); // equivalent to std::make_pair(1, 2)
make<std::binder2nd>(&foo, 3); // equivalent to std::bind2nd(&foo, 3);
Run Code Online (Sandbox Code Playgroud)
有可能写这个功能make吗?我试过这个,但它在GCC 4.5或4.6中不起作用:
template <template <typename...> class TemplateClass, typename... Args>
TemplateClass<Args...> make(Args&&... args)
{
return TemplateClass<Args...>(std::forward<Args>(args)...);
}
Run Code Online (Sandbox Code Playgroud)
如果我试着打电话(例如)make<std::pair>(1, 2)我就得到
error: no matching function for call to 'make(int, int)'
Run Code Online (Sandbox Code Playgroud)
我在这里的语法错了吗?
或者这是对的,海湾合作委员会是错的吗?
或者这在C++ 0x中根本不可能?
[编辑]
建议N2555似乎表明这是允许的,海湾合作委员会声称已在GCC4.4中实施.
我写了一个可变参数模板,它接受可变数量的char参数,即
template <char... Chars>
struct Foo;
Run Code Online (Sandbox Code Playgroud)
我只是想知道是否有任何宏技巧允许我使用类似于以下语法实例化它:
Foo<"abc">
Run Code Online (Sandbox Code Playgroud)
要么
Foo<SOME_MACRO("abc")>
Run Code Online (Sandbox Code Playgroud)
要么
Foo<SOME_MACRO(abc)>
Run Code Online (Sandbox Code Playgroud)
等等
基本上,任何阻止你单独写字符的东西,就像这样
Foo<'a', 'b', 'c'>
Run Code Online (Sandbox Code Playgroud)
这对我来说不是一个大问题,因为它只是一个玩具程序,但我想我还是会问.
根据广义常量表达式 - 修订版5,以下是非法的.
constexpr int g(int n) // error: body not just ‘‘return expr’’
{
int r = n;
while (--n > 1) r *= n;
return r;
}
Run Code Online (Sandbox Code Playgroud)
这是因为所有'constexpr'函数都必须具有这种形式{ return expression; }.我看不出有任何理由需要这样做.
在我看来,唯一真正需要的是不读取/写入外部状态信息,传入的参数也是'constexpr'语句.这意味着对具有相同参数的函数的任何调用都将返回相同的结果,因此可以在编译时"知道".
我的主要问题是,它似乎只是强迫你做一些真正的回旋形式的循环,并希望编译器优化它,以便它对非constexpr调用同样快.
要constexpr为上面的例子写一个有效的,你可以这样做:
constexpr int g(int n) // error: body not just ‘‘return expr’’
{
return (n <= 1) ? n : (n * g(n-1));
}
Run Code Online (Sandbox Code Playgroud)
但是这很难理解,你必须希望编译器在使用违反要求的参数调用时处理尾递归const-expr.
在C++ 0x中,您可以使用using关键字继承构造函数,如下所示:
class B { B(int) {} };
class A : public B { using B::B; };
Run Code Online (Sandbox Code Playgroud)
这将隐式声明一个A(int)构造函数.这适用于模板吗?
class B { B(int) {} };
template<class T> class A : public T { using T::T; };
Run Code Online (Sandbox Code Playgroud)
在内部T::T,我希望编译器找出左手,T因为在模板参数上使用范围运算符是正常的,但是确定右手T是构造函数是一种特殊情况.事实上,它似乎有歧义:如果我有一个名为方法T中B,我试图以重载在增加A(这是一个编译器会如何解释这种使用预申报的C++ 0x)?
我知道这可能是一个愚蠢的问题..我什么时候需要编写自己的迭代器?是在设计我自己的容器类时吗?还有其他什么时候我想创建自己的迭代器吗?
例子将被挪用.
-Jon
我有一个具有私有属性向量rectVec的类;
class A {
private:
vector<Rect> rectVec;
};
Run Code Online (Sandbox Code Playgroud)
我的问题是如何返回我的Vector的"只读"副本?我在想这样做:
class A {
public:
const vect<Rect>& getRectVec() { return rectVect; }
}
Run Code Online (Sandbox Code Playgroud)
这是正确的方法吗?我在想这可以防止被调用者修改向量(在向量中添加/删除Rect),向量内的Rect怎么样?
我正在阅读关于未定义行为的本文,其中一个示例"优化"看起来非常可疑:
Run Code Online (Sandbox Code Playgroud)if (arg2 == 0) ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), errmsg("division by zero"))); /* No overflow is possible */ PG_RETURN_INT32((int32) arg1 / arg2);图2:意外的优化使
src/backend/utils/adt/int8.cPostgreSQL中的除零检查无效.该召唤ereport(ERROR, :::)将引发异常.
从本质上讲,编译器假定这ereport将返回,并删除arg2 == 0,因为分工的存在意味着一个非零分母检查,即arg2 != 0.
这是一个有效的优化吗?编译器是否可以自由地假设函数将始终返回?
编辑:整个事情取决于ereport,因此描述:
84 /*----------
85 * New-style error reporting API: to be used in this way:
86 * ereport(ERROR,
87 * (errcode(ERRCODE_UNDEFINED_CURSOR),
88 * errmsg("portal \"%s\" not found", stmt->portalname),
89 * ... other errxxx() fields as …Run Code Online (Sandbox Code Playgroud) c++ ×10
c++11 ×4
c ×2
standards ×2
auto-ptr ×1
constructor ×1
inheritance ×1
iterator ×1
optimization ×1
pointers ×1
rationale ×1
stl ×1
string ×1
unique-ptr ×1