“ std_lib_facilities.h”显示错误

时间:2018-07-12 20:01:51

标签: c++ header

我正在使用代码块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",因为它使用的是不赞成使用的标题或过时的标题。

6 个答案:

答案 0 :(得分:1)

  

我们完全不应使用此文件“ 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>

放在一个单独的头文件中,但是要与所有翻译单元保持同步尤其麻烦,


另一个相关的问答:

Why should I not #include <bits/stdc++.h>?

答案 1 :(得分:1)

这是我在装有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++ language dialect

中更改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 exit\n";
    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 exit\n";
        string ss;
        while (cin >> ss && ss!=s)
            cout << "Please enter " << s << " to exit\n";
        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

答案 2 :(得分:1)

实际上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; 

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

答案 3 :(得分:0)

我还没有阅读您参考的那本书,但是您可以尝试切换到<iostream>,并且程序将编译而没有任何错误。

我猜“ std_lib_facilities.h”更多是占位符,而不是逼真的标题。

答案 4 :(得分:0)

该文件的更新版本对ISO / IEC 14882标准的最新版本(即C ++ 17)正常工作。

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

您不需要该行:

#include<iostream> 

希望您不会因为那本精彩的书而停止学习C ++!

答案 5 :(得分:0)

使用更新的标头可能是最好的解决方案。对于那些对此特定错误感兴趣的人:它似乎是由

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

在此宏之后包含<iomanip>时,gcc会出错。如果以前包含它,则gcc可以正常编译。 (注意:仅当_MSC_VER<1500时才启用此宏;根据注释,“ MS C ++ 9.0”未获得此宏。)

这是一个关于为什么不推荐黑客的对象课程。他们会随着时间的流逝而消失。