显示错误"std_lib_facilities.h"

"std_lib_facilities.h" showing error

本文关键字:facilities lib std 错误 显示      更新时间:2023-10-16

我使用的是代码块17.12,并且已经将编译器设置为C++11标准。我正在学习Bjarne Stroustrup的书"编程-使用C++的原理和实践"。在他的书中,他要求包含"std_lib_facilities.h"。我从他的网站上复制了它,并保存在"Mingw"文件夹的"include"文件夹中。之后,我开始制作一个简单的程序:

#include<iostream>
#include "std_lib_facilities.h"
main()
{
std::cout<<"Hello world";
}

但编译器显示以下错误和警告:

warning: This file includes at least one deprecated or antiquated header which may be removed without further notice at a future date.  
Please use a non-deprecated interface with equivalent functionality instead. 
For a listing of replacement headers and interfaces, consult the file backward_warning.h. To disable this warning use -Wno-deprecated. [-Wcpp]
error: template-id 'do_get<>' for 'String > 
std::__cxx11::messages<char>::do_get(std::messages_base::catalog, int, int, const String&) const' does not match any template declaration
note: saw 1 'template<>', need 2 for specializing a member function template

显示的错误也在头文件"locale_facets_nonio.h"的1971行中
我试图在其他论坛上找到这个问题的解决方案,但没有找到满意的答案
有些人说我们根本不应该使用这个文件"std_lib_facilities.h",因为它使用的是不推荐使用或过时的标头。

该文件的更新版本适用于ISO/IEC 14882标准的最新修订版,即C++17。

https://github.com/BjarneStroustrup/Programming-_Principles_and_Practice_Using_Cpp/blob/master/std_lib_facilities.h

你不需要那行:

#include<iostream> 

希望你没有因为那本精彩的书而放弃学习C++!

我们根本不应该使用这个文件"std_lib_facilities.h",因为它使用的是不推荐使用或过时的标头。

您应该在使用#include标准标头时使用它们。std_lib_facilities.h可能不同步。

#include<iostream>
#include "std_lib_facilities.h"
int main() {
std::cout<<"Hello world";
}

应该是

#include<iostream>
// #include "std_lib_facilities.h" Remove this entirely!
int main() {
std::cout<<"Hello world";
}

使用std::string等更标准的功能应该是:

#include<iostream>
#include<string>
int main() {
std::string hello = "Hello world";
std::cout<<hello;
}

进一步扩展,阅读书籍中的#include std_lib_facilities.h示例可能会扩展可编译和高效代码的实际必要的标准头包含
这只是Coliru 使用的默认启动模板

#include <iostream>
#include <vector>
template<typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& vec)
{
for (auto& el : vec)
{
os << el << ' ';
}
return os;
}
int main()
{
std::vector<std::string> vec = {
"Hello", "from", "GCC", __VERSION__, "!" 
};
std::cout << vec << std::endl;
}

当然你可以收集

#include <iostream>
#include <vector>

在一个单独的头文件中,但要与您需要的内容保持同步,尤其是与所有翻译单元保持同步,这将是乏味的。


另一个相关的问答;A:

为什么我不应该#include<bits/stdc++.h>

这就是我如何在安装了Xcode的Mac上使用C++11到17的方法。我正在学习Bjarne Stroustrup的教科书《编程:使用C++的原理和实践》。以下内容允许您按照C++先生自己的意愿来阅读课本。这对我来说非常适用于Xcode和终端上的std_lib_facilities.h。这正是我所做的,以使它发挥作用,并涉及到故障排除,这有望为您节省一些时间。

这是我的.cpp文件

// This program outputs the message "Hello, World!"
#include "std_lib_facilities.h"
int main()  // C++ programs start by executing the function main
{
cout<<"Hello, World!n";    // output "Hello, World!"
keep_window_open();         //wait for a character to be entered
return 0;
}

Stroustrup使用一个名为std_lib_facilities.h的自定义头文件,但为了使其正常工作,我不得不进行一些更改,因为在使用当前位于他的网站上的文件进行编译时发生了一些错误。如果代码如上所述,则它必须与.cpp位于同一文件夹中。

在Xcode上,您可以在项目的构建设置中更改C++版本C++语言方言

在Mac上,我使用clang++而不是g++来通过终端编译文件(这些文件带有Xcode(。为了让终端使用clang和g++,我必须启用由命令xcode-select --reset触发的开发人员工具权限。你必须指定c++版本,否则你会收到一堆警告,例如

clang++ hello_world.cpp -std=c++14
./a.out

对于.h->std::添加在每个ios_base之前,而不是用于uniform_int_distribution的花括号

将现有的std_lib_facilities.h文件替换为以下文件:

/*
std_lib_facilities.h
*/
/*
simple "Programming: Principles and Practice using C++ (second edition)" course header to
be used for the first few weeks.
It provides the most common standard headers (in the global namespace)
and minimal exception/error support.
Students: please don't try to understand the details of headers just yet.
All will be explained. This header is primarily used so that you don't have
to understand every concept all at once.
By Chapter 10, you don't need this file and after Chapter 21, you'll understand it
Revised April 25, 2010: simple_error() added
Revised November 25 2013: remove support for pre-C++11 compilers, use C++11: <chrono>
Revised November 28 2013: add a few container algorithms
Revised June 8 2014: added #ifndef to workaround Microsoft C++11 weakness
Revised Febrary 2 2015: randint() can now be seeded (see exercise 5.13).
Revised June 15 for defaultfloat hack for older GCCs
*/
#ifndef H112
#define H112 020215L

#include<iostream>
#include<iomanip>
#include<fstream>
#include<sstream>
#include<cmath>
#include<cstdlib>
#include<string>
#include<list>
#include <forward_list>
#include<vector>
#include<unordered_map>
#include<algorithm>
#include <array>
#include <regex>
#include<random>
#include<stdexcept>
//------------------------------------------------------------------------------
#if __GNUC__ && __GNUC__ < 5
inline std::ios_base& defaultfloat(std::ios_base& b)    // to augment fixed and scientific as in C++11
{
b.setf(std::ios_base::fmtflags(0), std::ios_base::floatfield);
return b;
}
#endif
//------------------------------------------------------------------------------
using Unicode = long;
//------------------------------------------------------------------------------
using namespace std;
template<class T> string to_string(const T& t)
{
ostringstream os;
os << t;
return os.str();
}
struct Range_error : out_of_range { // enhanced vector range error reporting
int index;
Range_error(int i) :out_of_range("Range error: "+to_string(i)), index(i) { }
};

// trivially range-checked vector (no iterator checking):
template< class T> struct Vector : public std::vector<T> {
using size_type = typename std::vector<T>::size_type;
#ifdef _MSC_VER
// microsoft doesn't yet support C++11 inheriting constructors
Vector() { }
explicit Vector(size_type n) :std::vector<T>(n) {}
Vector(size_type n, const T& v) :std::vector<T>(n,v) {}
template <class I>
Vector(I first, I last) : std::vector<T>(first, last) {}
Vector(initializer_list<T> list) : std::vector<T>(list) {}
#else
using std::vector<T>::vector;   // inheriting constructor
#endif
T& operator[](unsigned int i) // rather than return at(i);
{
if (i<0||this->size()<=i) throw Range_error(i);
return std::vector<T>::operator[](i);
}
const T& operator[](unsigned int i) const
{
if (i<0||this->size()<=i) throw Range_error(i);
return std::vector<T>::operator[](i);
}
};
// disgusting macro hack to get a range checked vector:
#define vector Vector
// trivially range-checked string (no iterator checking):
struct String : std::string {
using size_type = std::string::size_type;
//  using string::string;
char& operator[](unsigned int i) // rather than return at(i);
{
if (i<0||size()<=i) throw Range_error(i);
return std::string::operator[](i);
}
const char& operator[](unsigned int i) const
{
if (i<0||size()<=i) throw Range_error(i);
return std::string::operator[](i);
}
};

namespace std {
template<> struct hash<String>
{
size_t operator()(const String& s) const
{
return hash<std::string>()(s);
}
};
} // of namespace std

struct Exit : runtime_error {
Exit(): runtime_error("Exit") {}
};
// error() simply disguises throws:
inline void error(const string& s)
{
throw runtime_error(s);
}
inline void error(const string& s, const string& s2)
{
error(s+s2);
}
inline void error(const string& s, int i)
{
ostringstream os;
os << s <<": " << i;
error(os.str());
}

template<class T> char* as_bytes(T& i)  // needed for binary I/O
{
void* addr = &i;    // get the address of the first byte
// of memory used to store the object
return static_cast<char*>(addr); // treat that memory as bytes
}

inline void keep_window_open()
{
cin.clear();
cout << "Please enter a character to exitn";
char ch;
cin >> ch;
return;
}
inline void keep_window_open(string s)
{
if (s=="") return;
cin.clear();
cin.ignore(120,'n');
for (;;) {
cout << "Please enter " << s << " to exitn";
string ss;
while (cin >> ss && ss!=s)
cout << "Please enter " << s << " to exitn";
return;
}
}

// error function to be used (only) until error() is introduced in Chapter 5:
inline void simple_error(string s)  // write ``error: s and exit program
{
cerr << "error: " << s << 'n';
keep_window_open();     // for some Windows environments
exit(1);
}
// make std::min() and std::max() accessible on systems with antisocial macros:
#undef min
#undef max

// run-time checked narrowing cast (type conversion). See ???.
template<class R, class A> R narrow_cast(const A& a)
{
R r = R(a);
if (A(r)!=a) error(string("info loss"));
return r;
}
// random number generators. See 24.7.
default_random_engine& get_rand()
{
static default_random_engine ran;
return ran;
};
void seed_randint(int s) { get_rand().seed(s); }
inline int randint(int min, int max) {  return uniform_int_distribution<>(min, max)(get_rand()); }
inline int randint(int max) { return randint(0, max); }
//inline double sqrt(int x) { return sqrt(double(x)); } // to match C++0x
// container algorithms. See 21.9.
template<typename C>
using Value_type = typename C::value_type;
template<typename C>
using Iterator = typename C::iterator;
template<typename C>
// requires Container<C>()
void sort(C& c)
{
std::sort(c.begin(), c.end());
}
template<typename C, typename Pred>
// requires Container<C>() && Binary_Predicate<Value_type<C>>()
void sort(C& c, Pred p)
{
std::sort(c.begin(), c.end(), p);
}
template<typename C, typename Val>
// requires Container<C>() && Equality_comparable<C,Val>()
Iterator<C> find(C& c, Val v)
{
return std::find(c.begin(), c.end(), v);
}
template<typename C, typename Pred>
// requires Container<C>() && Predicate<Pred,Value_type<C>>()
Iterator<C> find_if(C& c, Pred p)
{
return std::find_if(c.begin(), c.end(), p);
}
#endif //H112

实际上std_lib_facilities.h是由Bjarne Stroustrup创建的,旨在帮助编程初学者。你也可以在他的网站上找到:std_lib_facilities.h因此,您的系统中可能不存在此头文件。Bjarne Stroustrup也知道你可能会得到错误,所以他在书中告诉用:-代替它

//these header files are equivalent to std_lib_facilities.h 
#include <iostream>
#include <string>
#include <cmath>
#include <algorithm>
using namespace std; 

希望这能有所帮助(^人^)

我还没有读过你提到的那本书,但你可以尝试切换到<iostream>,你的程序编译时不会有任何错误。

我猜"std_lib_facilities.h"与其说是一个实际的头,不如说是一种占位符。

使用更新的标头可能是最好的解决方案。对于那些对这个特殊错误感兴趣的人来说:它似乎是由引起的

// disgusting macro hack to get a range checked string:
#define string String

<iomanip>包含在此宏之后时,gcc会出现错误。如果之前包含它,gcc编译良好。(注意:此宏仅在_MSC_VER<1500时启用;根据注释"MS C++9.0"未获得此宏。(

这是一堂关于为什么不建议使用黑客的实物课。它们会随着时间的推移而断裂。