Reputation: 2199
For some odd reason I am having difficulties throwing an exception in C++. I throw without catching std::invalid_argument
from the stdexcept header file. I have no real intention of catching as i want the application to fail anyway if the error occurs.
It seemed to be working fine until I #included the function definition class into the namespace of the header declaration. It was added outside of the namespace prior since they are template definitions and I wanted to separate the header from its definition; however, I realized this caused a subtle issue that I did not realized until only recently.
Is their something I am missing? I am using clang btw
Project Compilation
.
.
.
.
.
Compiling CPP file TrieTest.cpp ...
In file included from TrieTest.cpp:4:
In file included from ./Trie.hpp:62:
In file included from ./Trie.cpp:2:
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/stdexcept:55:30: error: unknown class name 'exception'; did you mean
'::std::exception'?
class logic_error : public exception
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/exception:60:9: note: '::std::exception' declared here
class exception
^
In file included from TrieTest.cpp:4:
In file included from ./Trie.hpp:62:
In file included from ./Trie.cpp:2:
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/stdexcept:112:32: error: expected class name
class runtime_error : public exception
^
2 errors generated.
EDIT: A bit of the src Also I compile with clang++ -Wall -Wextra -g -std=c++11 TrieTest.cpp -o TrieTest;
"Trie.h"
#ifndef COM_WORDGAME_UTILITY_TRIE_HPP
#define COM_WORDGAME_UTILITY_TRIE_HPP
#include <string>
using std::string;
namespace wordgame_utility{
template<typename value>
class Trie{
...Trie Function Declarations
};
//The compiler may not complain initialliy however
//Templates cause visibility issues with user code and is normally defined in the header
//this is a work around
#include "Trie.cpp"
}
#endif
"Trie.cpp" head -n 8
#include "Trie.hpp"
#include <stdexcept>
using namespace wordgame_utility;
template<typename value>
using TrieNode = typename Trie<value>::TrieNode;
...Trie Function Definitions
Upvotes: 0
Views: 2770
Reputation: 300159
You have a cyclic include in your code.
Trie.hpp
includes Trie.cpp
which includes Trie.hpp
. This is not meant to work in C++, where include
is a literal inclusion (think, copy/pasting the included file at the point of the #include
directive).
You need to define template methods into the header, or into a third file, that's all there is.
What is the effect of this cycle ? In general, poor error messages, as you can see by yourself.
In your case... let's play preprocessor ourselves:
// begin #include "Trie.hpp"
#define COM_WORDGAME_UTILITY_TRIE_HPP
// begin #include <string>
namespace std {
...
}
// end #include <string>
using std::string;
namespace wordgame_utility{
template<typename value>
class Trie{
...Trie Function Declarations
};
//The compiler may not complain initialliy however
//Templates cause visibility issues with user code
// and is normally defined in the header
//this is a work around
// begin #include "Trie.cpp"
// begin #include "Trie.hpp"
// -- empty because of the include guards --
// end #include "Trie.hpp"
// begin #include <stdexcept>
namespace std {
class logic_exception: public exception { };
}
// end #include <stdexcept>
using namespace wordgame_utility;
template<typename value>
using TrieNode = typename Trie<value>::TrieNode;
...Trie Function Definitions
// end #include "Trie.cpp"
} // namespace wordgame_utility
// end #include "Trie.hpp"
As you can see, it's a mess. The combination of using #include
within an open namespace and having cyclic includes is downright ugly.
Fortunately, in the (near ?) future, this will be improved if modules are adopted, which are just a much saner alternative to textual inclusion.
Upvotes: 4