下面的代码编译(gcc 4.7.2或icc 13)并产生"1 2"输出.这意味着const限定符被删除,即f<int&>具有参数类型int&.
为什么会这样?据我了解,根据§14.3.1.4:
如果一个模板参数的模板参数
T名称的类型"参考CV1S",企图制造型"参考CV2T"创造型"参考CV12S",其中CV12是CV-合格网络ERS的联合CV1和cv2.冗余的cv-quali firs被忽略.
const不应该被丢弃.这是代码:
#include <iostream>
using namespace std;
template <typename T>
void f(const T& t)
{
t++;
}
int main()
{
int a = 1;
cout << a;
f<int&>(a);
cout << ' ' << a << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud) 这段代码:
std::vector<int>(boost::assign::list_of<int>(1)(2)(3));
Run Code Online (Sandbox Code Playgroud)
给出错误:
main.cpp: In member function 'void <unnamed>::RequestHandler::processRequest(Foo&, Bar, unsigned int, unsigned int*, const char*, boost::shared_ptr<Baz::IOutput>&)':
main.cpp:450: error: call of overloaded 'vector(boost::assign_detail::generic_list<int>&)' is ambiguous
/4.4.2/bits/stl_vector.h:241: note: candidates are: std::vector<_Tp, _Alloc>::vector(const std::vector<_Tp, _Alloc>&) [with _Tp = int, _Alloc = std::allocator<int>]
/4.4.2/bits/stl_vector.h:227: note: std::vector<_Tp, _Alloc>::vector(size_t, const _Tp&, const _Alloc&) [with _Tp = int, _Alloc = std::allocator<int>]
/4.4.2/bits/stl_vector.h:215: note: std::vector<_Tp, _Alloc>::vector(const _Alloc&) [with _Tp = int, _Alloc = std::allocator<int>]
Run Code Online (Sandbox Code Playgroud)
当为gcc 4.4.2编译时.
我该如何解决这个问题?最终我正在尝试编译以下内容:
using namespace std;
using namespace boost::assign;
typedef boost::variant<vector<bool>, vector<int>, vector<string> …Run Code Online (Sandbox Code Playgroud) 假设我有一个常量值(可能是一些枚举类型).假设我有很多A,B,D等课程.
我能有这样的东西吗?
C<1> anInstanceOfA; //This will be of type A
C<2> anInstanceOfB; //This will be of type B
C<3> anInstanceOfD; //This will be of type D
Run Code Online (Sandbox Code Playgroud)
那么,是否可以在编译时根据常数选择一个类?
一般的问题是我试图根据表选择一个仿函数,其中索引是一个枚举.如果可能的话,我想避免多态性.
编辑:对于这个项目我不能使用C++ 11,无论如何,感谢谁在那个环境中回答,无论如何都知道非常有趣.
编辑2:一般来说,我可以有两个以上的目标类,我编辑了我的问题
以下代码不能在Visual C++ 2008和2010上编译:
#include <memory>
struct A {};
std::auto_ptr<A> foo() { return std::auto_ptr<A>(new A); }
const std::auto_ptr<A> bar() { return std::auto_ptr<A>(new A); }
int main()
{
const std::auto_ptr<A> & a = foo(); // most important const
const std::auto_ptr<A> & b = bar(); // error C2558:
// class 'std::auto_ptr<_Ty>' :
// no copy constructor available or copy
// constructor is declared 'explicit'
bar(); // No error?
}
Run Code Online (Sandbox Code Playgroud)
我期望"最重要的const"应用于变量"b",然而,它不会编译,并且由于某种原因,编译器要求复制构造函数(这让我感到惊讶,因为这里不应该涉及复制) .独立调用bar()工作正常,这意味着,我猜,它实际上是初始化b的问题.
这是编译器错误,还是标准中描述的真正的编译错误?
(也许它在C++ 98中被禁止并在C++ 11中被授权?)
注意:它在Visual C++ 2012,gcc 4.6和Solaris …
所以我正在阅读关于lambda演算的模板元程序的实现,这是TMP图灵完备性的一个证明.
当我阅读源代码时,我偶然发现了一行(然后更多),如下所示:
template <int Name, typename Value, typename Env>
struct EnvLookup <Name, Binding<Name,Value,Env> >
{
Value typedef result ; // Line 84, what is this ?
} ;
Run Code Online (Sandbox Code Playgroud)
我已经习惯了typedef Type Alias;,但Type typedef Alias;对我来说却很陌生.而且它仍然可以用g ++ 4.9.0编写好的版本-std=c++98.
我在Google上找不到关于这种语法的任何文档,也没有关于SO的文档.这是否符合标准?也许是一个g ++扩展?它会融合吗 ?
的元问题提出了C++ 98级C++ 03的标签应作出的同义词.问题提问者跟着它进行了C++ 98标准的Is值初始化部分?如果没有,为什么它被添加到C++ 03标准中?,一个很好的问题,它揭示了向C++ 03 添加值初始化.考虑这个问题是后者的后续行动.
OP断言现代编译器不打扰区分C++ 98和C++ 03.这对我来说是令人惊讶的,因为事实证明是三个现代编译器的情况.虽然这个问题可以归结为"RTFM",但我的搜索还没有找到任何结论.
他们的标准页面:
最初的ISO C++标准作为ISO标准(ISO/IEC 14882:1998)公布,并由2003年出版的技术勘误表(ISO/IEC 14882:2003)进行了修订.这些标准分别称为C++ 98和C++ 03.GCC实现了大部分C++ 98(导出是一个值得注意的例外)和C++ 03中的大多数更改.要在GCC中选择此标准,请使用以下选项之一-ansi,-std = c ++ 98或-std = c ++ 03; ...
此外,他们的方言选项页面说:
在C++模式下,[ansi]相当于-std = c ++ 98.
并将"c ++ 98"和"c ++ 03"组合在一起:
1998 ISO C++标准加上2003年技术勘误和一些额外的缺陷报告.与C++代码的-ansi相同.
这似乎意味着没有办法只打开C++ 98模式.
我发现Clang唯一找到的就是他们的手册,它在C++语言特性下说:
clang完全实现了所有标准C++ 98,除了导出的模板(在C++ 11中被删除),...
没有提到C++ 03.它还指出:
clang支持-std选项,它可以更改clang使用的语言模式.C的支持模式是c89,gnu89,c94,c99,gnu99,c11,gnu11以及这些模式的各种别名.如果未指定-std选项,则clang默认为gnu11模式.早期模式支持许多C99和C11功能作为符合标准的扩展,并带有警告.
这当然是他们的C编译器,我无法在C++编译器上找到任何文档,例如哪些选项有效传递给它们-std.我只是假设Clang镜像GCC的方言选项(例如,C++ 03在Clang上有效),虽然没有证据我不能这么说.
据我所知,MSVC不允许你像上面两个那样改变语言标准.在MSDN …
考虑变体类型和模板函数,如何检查模板类型是变体的类型之一?有比以下更优雅的方式吗?
typedef boost::variant<Foo,Bar> Var;
template <typename T>
void f(const T& x)
{
BOOST_STATIC_ASSERT(
boost::is_same<T,Foo>::value
|| boost::is_same<T,Bar>::value
);
}
Run Code Online (Sandbox Code Playgroud)
注意:我使用Boost 1.57和gcc 4.8.3.我不使用C++ 11与旧的gcc版本兼容.
我写了以下程序
#include <iostream>
#include <stdexcept>
class Myclass
{
public:
~Myclass()
{
//throw std::runtime_error("second (in destructor)");
throw 1;
}
};
void fun()
{
Myclass obj;
}
int main()
{
try
{
fun();
}
catch (const std::exception& e)
{
std::cout << e.what();
}
catch(...)
{
std::cout << " ... default Catch" << std::endl;
}
std::cout << "Normal" << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我在C++98模式(cpp.sh)上运行程序时,它会打印出来
... default Catch
Normal
Run Code Online (Sandbox Code Playgroud)
当我使用C++14模式运行它时,它不会打印任何内容. 为什么这种行为有变化?
我确实理解,每当发生任何异常并且任何destructor(在堆栈展开过程中)抛出任何异常时,它都会终止应用程序.但是这里只有一次异常从try块中抛出destructor.
struct Data
{
...
CRITICAL_SECTION valLock;
}
std::map<int, Data> mp;
CRITICAL_SECTION mpLock;
Run Code Online (Sandbox Code Playgroud)
我目前正在使用两个关键部分来确保该线程安全。
我必须锁定两者map并Data更新Data
//Lock mpLock
//Lock mp[key1].valLock
mp[key1].something = something_new;
//unlock mp[key1].valLock
//unlock mpLock
Run Code Online (Sandbox Code Playgroud)
我研究了英特尔的并发哈希图,它不需要两个锁并在内部处理这个问题。如果我不想使用英特尔的tbb,还有其他方法吗?我只有支持。不过c++ 98可以使用。boost调查过boost::shared_mutex,但无法关联如何在当前场景中使用它。
编辑:容器上的锁真的需要吗?我不能用来Data::valLock读/写Data。任何插入mp都不会影响现有的迭代器,因此不需要锁。任何删除mp都会以 开头Data::valLock。这里可能会错过什么情况?
编辑2:
UpdateThread()
{
//Lock mp[key].valLock
mp[key].a = b; //Line 1
//unlock mp[key].valLock
}
ReadThread()
{
//Lock mp[key].valLock
something = mp[key].a; //Line 2
//unlock mp[key].valLock
}
Run Code Online (Sandbox Code Playgroud)
所以我认为只有当第 1 行完成(或反之亦然)即已mp更新(以及地图内部结构)时,第 …
#include <iostream>
#include <vector>
using namespace std;
int main(void){
vector<int> a;
a.push_back(3);
vector<int> b = move(a);
cout<<"b: "<<b.data()<<endl;
cout<<"a: "<<a.data()<<endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出(在 c++98 中):
#include <iostream>
#include <vector>
using namespace std;
int main(void){
vector<int> a;
a.push_back(3);
vector<int> b = move(a);
cout<<"b: "<<b.data()<<endl;
cout<<"a: "<<a.data()<<endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出(在 C++11 中):
b: 0x7f9a82405730
a: 0x7f9a82405720
Run Code Online (Sandbox Code Playgroud)
我正在使用 Apple clang 11.0.3。
第一个输出不使用编译器标志。
-std=c++11 第二个输出的标志。
我知道 move() 在 c++11(和更高版本)中做什么。但是正如我所看到的,在 c++98 中使用 move() 对传递的对象没有任何作用,只会发生深拷贝。
那为什么 c++98 中有 move() 呢??