我需要一个只读的std:map数据结构,这意味着我必须用数据填充一次,然后只读取这些值,永远不要更改它们或添加其他值.
我的非const版本看起来像这样:
//in .h
#include <string>
#include <map>
std::map<std::string, int> myMap;
void initMap();
//in .cpp
#include "foo.h"
void initMap() {
myMap["Keys"] = 42;
}
Run Code Online (Sandbox Code Playgroud)
然后我会initMap()在我的代码中调用一次并完成.
现在我已经在这里阅读了几个问题,实现地图的常数似乎并非易事.
制作它std::map<std::string, const int>不会让我填写它initMap().使用非const temp填充它并且定义上的复制构造函数也不起作用,因为复制构造函数不容易将非const版本作为输入.
使它成为const std::map<std::string, int>(我可以在定义期间填充非const副本)将禁止使用[]运算符进行值访问.
那么有没有办法实现(值)const-ness并初始化结构(最好是在头文件中)?
顺便说一句:C++ 0x和C++ 11也不boost::是一个选项.
所以我正在阅读关于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++ 14)代码:
template <void (&a)()>
struct Foo {
static auto value() {}
};
void bar() {}
template struct Foo<Foo<bar>::value>;
Run Code Online (Sandbox Code Playgroud)
GNU C++ "g ++(Ubuntu 5.1.0-0ubuntu11~14.04.1)5.1.0"编译器发出:
error: could not convert template argument ‘Foo<a>::value<bar>’ to ‘void (&)()’
template struct Foo<Foo<bar>::value>;
^
Run Code Online (Sandbox Code Playgroud)
我注意到的第一个奇怪的事情是Foo<a>::value<bar>- a没有被替换,并且value以某种方式成为模板?
以下无意义的修复增强了我的印象,这是一个编译器错误:
value()返回void而不是推断它value:template struct Foo<*Foo<bar>::value>;value:template struct Foo<(Foo<bar>::value)>;a指针:template <void (*a)()> struct Foo ...最后,Clang编译我的片段很好.
那么,某个禁止第一个片段的地方是否有一个模糊的标准条款,或者GCC刚刚死在我身上?
不确定是否可以使用更高版本的c ++.(我无法弄清楚使用传统的c ++来实现以下行为.)
例如,
如果我有一个像这样定义的数组:
在头文件中
struct Def {
static const int N = 5;
static const double data[N];
};
Run Code Online (Sandbox Code Playgroud)
在它的cpp
const double Def::data[Def::N] = {0,1,2,3,4};
Run Code Online (Sandbox Code Playgroud)
是否有可能有一个模板get_subarray,使得
get_subarray<Def,2,0>::data 将是一系列内容 {0,2,4}
get_subarray<Def,2,1>::data 将是一系列内容 {1,3}
哪里
template<typename T, int M, int m>
struct get_phase {
// some code for the array variable data which will
// extract element from T::data for every M sample offset by index m
};
Run Code Online (Sandbox Code Playgroud) 只是一个简短的问题给出一个函数,我想返回一个基础类型enum class:
为什么这个版本工作正常
template<typename T>
constexpr inline
typename std::enable_if_t<
std::is_enum<T>::value,
typename std::underlying_type_t<T>
>
enumValue(T p_rVal) noexcept
{
return static_cast<typename std::underlying_type_t<T>>(p_rVal);
}
if (enumValue(myEnumClass) == 0) {}
Run Code Online (Sandbox Code Playgroud)
而这一个失败了" 找不到匹配的重载函数 "(VS 2015)错误:
template<
typename T,
typename std::enable_if_t<
std::is_enum<T>::value,
typename std::underlying_type_t<T>
>
>
constexpr inline
typename std::underlying_type_t<T>
enumValue(T p_rVal) noexcept
{
return static_cast<typename std::underlying_type_t<T>>(p_rVal);
}
Run Code Online (Sandbox Code Playgroud)
非常感谢您的帮助!
我们正在将Visual C ++项目切换到vc141工具链(VS 2017)。我们遇到了一个问题,Visual Studio无法使用.pdb其源文件.obj文件不再存在的文件(例如,因为它们已在构建服务器上编译)。
让我们来看一个非常简单的可执行项目:
#include <iostream>
int main() {
std::cout << "Hello world\n";
std::cin.ignore();
}
Run Code Online (Sandbox Code Playgroud)
该.vcxproj文件是所有默认文件,除了<GenerateDebugInformation>true</GenerateDebugInformation>生成pdb文件外。
再现步骤始终使用VS2017:
mainDebug/包含.obj文件的中间目录这在vc100(VS 2010)工具链上可以正常工作,并且断点有效,但是它立即触发vc141的以下错误:

错误:无法打开文件
<path> \ Debug \ main.obj。错误代码= 0x80070003。
这个非常通用的错误代码确实对应FACILITY_WIN32/ERROR_PATH_NOT_FOUND。main.obj可以在.pdb文件的两个版本中找到的路径,因此我们不清楚为什么VS在找不到时突然崩溃。
“模块”视图显示.pdb文件似乎已正确加载。此外,断点的工具提示显示以下错误:

断点当前不会被命中。处理MyUser_141.exe时出现意外的符号读取器错误。
鉴于我们无法在编译实际应用程序中的二进制文件的机器上进行调试,该问题的解决方案或解决方法是什么?
这是完整的.vcxproj文件:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<RootNamespace>MyUser_141</RootNamespace> …Run Code Online (Sandbox Code Playgroud) 我刚刚遇到好奇的std :: experimental :: propagate_const错误.以下代码段演示了此问题
#include <memory>
#include <experimental/propagate_const>
#include <map>
class FWD;
//compiles
class A
{
std::unique_ptr<FWD> m;
};
//compiles
class B
{
std::experimental::propagate_const<std::unique_ptr<FWD>> m;
};
//compiles
class C
{
std::unique_ptr<std::map<int, FWD>> m;
};
//does not compile!
class D
{
std::experimental::propagate_const<std::unique_ptr<std::map<int, FWD>>> m;
};
Run Code Online (Sandbox Code Playgroud)
所以你不能只用传播的unique_ptr替换unique_ptr,因为有时你的前向声明会破坏它.
如果有人向我解释为什么编译在当前的propagate_const实现中失败,我将不胜感激.它与某些事情有关
typedef remove_reference_t<decltype(*std::declval<_Tp&>())> element_type;
Run Code Online (Sandbox Code Playgroud)
因为解决方法是:
template <typename T, typename = void>
struct get_element_type
{
using type = std::remove_reference_t<decltype(*std::declval<T&>())>;
};
template <typename T>
struct get_element_type<T, typename std::enable_if<!std::is_void<typename T::element_type>::value>::type>
{
using type = typename T::element_type; …Run Code Online (Sandbox Code Playgroud) 我有一个从容器条目生成组合的算法,我想找到最小化成本函数的组合:
struct Vec { double x; double y; };
double cost( Vec a, Vec b ) {
double dx = a.x - b.x;
double dy = a.y - b.y;
return dx*dx + dy*dy;
}
pair<Vec,Vec> get_pair_with_minimum_cost ( vector<Vec> inp, double (*cost_fun)(Vec,Vec) )
{
pair<Vec,Vec> result;
double min_cost = FLT_MAX;
size_t sz = inp.size();
for(size_t i=0; i<sz; i++) {
for (size_t j=i; j<sz; j++) {
double cost = cost_fun(inp[i], inp[j]);
if (cost < min_cost) {
min_cost = cost;
result = make_pair(inp[i], …Run Code Online (Sandbox Code Playgroud) 我正在尝试实现一个函数模板ovl,它ovl<Foo, Bar>(f)会返回ftake的重载(Foo, Bar),并且对我天真的解决方案所发生的事情感到非常惊讶:
template <class... Args, class Ret>
constexpr auto ovl(Ret (*const f)(std::type_identity_t<Args>...)) { return f; }
void foo();
void foo(int);
void foo(int, int);
int main() {
ovl<int>(foo)(0);
}
Run Code Online (Sandbox Code Playgroud)
prog.cc:26:5: fatal error: no matching function for call to 'ovl'
ovl<int>(foo)(0);
^~~~~~~~
prog.cc:6:16: note: candidate template ignored: couldn't infer template argument 'Ret'
constexpr auto ovl(Ret (*const f)(std::type_identity_t<Args>...)) { return f; }
^
Run Code Online (Sandbox Code Playgroud)
GCC 和 Clang 出现相同的错误。更重要的是,它实际上在自己枚举可能的参数时起作用:
template <class Ret>
constexpr auto ovl(Ret (*const …Run Code Online (Sandbox Code Playgroud) c++ templates overloading variadic-templates template-argument-deduction
我已经知道在c ++ 17中有一个std :: variant类型.看起来变体容器不支持预定义的数据类型,但是对于每种变体类型,用户可以定义自己的数据类型集.
std::variant<int, float> v;
Run Code Online (Sandbox Code Playgroud)
我想知道,类型列表可以多长时间?库是否具有用于Aleksandrescu方式的最大参数数量的预定义模板,或者是编译器支持的变体,并且类型的数量不受限制?