假设我有一些课程:
template <typename T>
class Foo {
const T* x_;
public:
Foo(const T* str) : x_{str} {}
};
Run Code Online (Sandbox Code Playgroud)
我提供了一些用户定义的文字来创建一个Foo对象:
Foo<char> operator"" _foo(const char* str, std::size_t) {
return Foo<char>{str};
}
Foo<wchar_t> operator"" _foo(const wchar_t* str, std::size_t) {
return Foo<wchar_t>{str};
}
// etc. for char16_t and char32_t.
Run Code Online (Sandbox Code Playgroud)
我的问题是:为什么我不能模板化这些并且不必重写代码?
template <typename T>
Foo<T> operator"" _foo(const T* str, std::size_t) {
return Foo<T>{str};
}
Run Code Online (Sandbox Code Playgroud)
gcc 5.4.0(Ubuntu 5.4.0-6ubuntu1~16.04.4)和7.0.0(自己编译)报告:
error: ‘Foo<T> operator""_foo(const T*, std::size_t)’ has invalid argument list
Foo<T> operator"" _foo(const T* str, std::size_t) { …Run Code Online (Sandbox Code Playgroud) 可能以前曾被问过,但所有这些都接近了我对C++的理解和认识的极限,所以我在理解被讨论的内容以及到底发生了什么方面有点慢.让我直接跳到代码.这有效:
template <typename T>
class Foo
{
struct Bar
{
Bar() {}
~Bar() noexcept {}
Bar(Bar&& b) : Bar() { swap(*this, b); }
friend void swap(Bar& b1, Bar& b2) { /* ... */ }
};
};
template class Foo<int>; // explicit instantiation of Foo with int type
Run Code Online (Sandbox Code Playgroud)
但是如何移动结构体swap外部的定义Bar呢?如果我这样做:
template <typename T>
class Foo {
struct Bar {
// ...
Bar(Bar&& b) : Bar() { swap(*this, b); } // line 16
// ...
template <typename V>
friend …Run Code Online (Sandbox Code Playgroud) 我有一个程序,我正在从使用数组切换到向量,但我遇到了问题.我把它减少到了这个:
#include <vector>
class A {
public:
A(void);
~A(void);
private:
std::vector< std::vector<int> > a;
};
A::A(void) : a() {}
A::~A(void) {}
Run Code Online (Sandbox Code Playgroud)
这给出了来自g ++(flags:-O2 -Wunsafe-loop-optimizations,版本4.4.3(Ubuntu 4.4.3-4ubuntu5)在Ubuntu 10.04 x86_64上)的以下警告:
/usr/include/c++/4.4/bits/stl_construct.h:在析构函数'A :: ~A()'中:/usr/include/c++/4.4/bits/stl_construct.h:92:警告:无法优化循环,循环计数器可能会溢出
那么,Leo给出了什么?矢量类不应该跟踪它有多少元素?那么,如果这是被引用的"计数器",它怎么会溢出?(编辑:这个问题或多或少已在下面得到解答,但是,对我来说,只留下必然结果:为什么还要警告库中的循环无法优化?为什么我,最终用户,应该关注那个问题? ?)
编辑:
这是关于被抱怨的相关代码(但是,正如我在评论中所说,我不明白为什么这应该是我的考虑因为我不应该担心库的实现):
/**
* Destroy the object pointed to by a pointer type.
*/
template<typename _Tp>
inline void
_Destroy(_Tp* __pointer)
{ __pointer->~_Tp(); }
template<bool>
struct _Destroy_aux
{
template<typename _ForwardIterator>
static void
__destroy(_ForwardIterator __first, _ForwardIterator __last)
{
for (; __first != __last; ++__first) // <-- this …Run Code Online (Sandbox Code Playgroud) (这不是一个迂腐运动的问题,所以这里就是这样.)
我已经制作了一个很好的小程序,这是我的Linux操作系统的原生程序,但我认为它在我的Windows机器上也很有用.因此,我想访问Windows的环境变量,MSDN引用了这样一个例子:
const DWORD buff_size = 50;
LPTSTR buff = new TCHAR[buff_size];
const DWORD var_size = GetEnvironmentVariable("HOME",buff,buff_size);
if (var_size==0) { /* fine, some failure or no HOME */ }
else if (var_size>buff_size) {
// OK, so 50 isn't big enough.
if (buff) delete [] buff;
buff = new TCHAR[var_size];
const DWORD new_size = GetEnvironmentVariable("HOME",buff,var_size);
if (new_size==0 || new_size>var_size) { /* *Sigh* */ }
else { /* great, we're done */ }
}
else { /* in one go! */ } …Run Code Online (Sandbox Code Playgroud) installcheck构建库时如何实现make 目标?也就是说,我有一个check,创建一个测试程序,它链接到创建的库,通过一些脚本,以所谓的检查,如果库代码功能正常的目标,我希望执行相同的检查,但链接到库后,它有已安装;我该如何实现呢?
我想知道我是否正确行事.我有一个包含一些数据的类:
class Foo {
// ...
Type a_;
Type b_;
Type c_;
};
Run Code Online (Sandbox Code Playgroud)
还有一个不同的类,它可以用其他东西构建class Foo.所以,我认为这样的ctor声明:
class Bar {
Type a_;
Type b_;
Type c_;
AnotherType A_;
AnotherType B_;
// ...
public:
typedef std::tuple<Type, Type, Type> Tuple;
Bar(const Tuple&);
Bar(Tuple&&);
};
Run Code Online (Sandbox Code Playgroud)
我现在需要创建一个Foo方法,它将返回Bar需要的数据成员的元组,我可以传递给它Bar的ctor.我也做了一个rvalue参考,Tuple因为class Foo除了via之外不再需要那些数据成员了class Bar,所以为什么在我移动数据时还要复制数据呢?
所以,我创建的方法class Foo将返回a Tuple.特别是,我需要一个可以由Bar使用右值引用的ctor使用的方法.以下是否正确?
auto Foo::move_data() -> Tuple&& {
return std::move( Tuple(a_, b_, c_) );
}
Run Code Online (Sandbox Code Playgroud)
或者这完全错了?(指出其他任何愚蠢的东西也会受到赞赏.当然,我遗漏了一些typedef和其他不必要的细节.)
c++ ×5
c++11 ×2
templates ×2
gcc ×1
install ×1
makefile ×1
optimization ×1
stl ×1
vector ×1
visual-c++ ×1