Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
575 views
in Technique[技术] by (71.8m points)

C++ template: cannot combine with previous 'type-name' declaration specifier

I'm writing a utility function to look for elements in containers like so:

#include <algorithm>
#include <type_traits>

// Helper to determine whether there's a const_iterator for T.
template <typename T>
struct hasConstIt {
private:
    template<typename C> static char test(typename C::const_iterator*);
    template<typename C> static int test(...);

public:
    enum { value = sizeof(test<T>(0)) == sizeof(char) };
};

// Check if a container contains an element.
template <typename Container>
typename std::enable_if<hasConstIt<Container>::value, void>::type
struct In {
    const Container & container;
    typename Container::value_type const & element;

    In(const Container & container, typename Container::value_type const & element) :
        container(container), element(element) {}

    bool operator()() const {
        return std::find(container.begin(), container.end(), element) != container.end();
    }
};

I took my solution from this stackoverflow question.

When I compile the code with g++ -std=c++17 I get the following error messages:

./util.hpp:19:1: error: cannot combine with previous 'type-name' declaration specifier
struct In {
^
./util.hpp:18:1: error: declaration does not declare anything [-Werror,-Wmissing-declarations]
typename std::enable_if<hasConstIt<Container>::value, void>::type

I have been looking for a solution but couldn't find one. Why is the compiler complaining here?

question from:https://stackoverflow.com/questions/65890083/c-template-cannot-combine-with-previous-type-name-declaration-specifier

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
template <typename Container>
typename std::enable_if<hasConstIt<Container>::value, void>::type
struct In {

is wrong. This is done as either

template <class Container, typename = std::enable_if_t<hasConstIt<Container>::value>>
struct In {

in old-fashioned C++11. Note the second argument: it has default value and is normally never specified explicitly but prevents instantiation when the predicate is unsatisfied.

Or, more modern,

template<class Container> requires (hasConstIt<Container>::value) struct In {

in C++20.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...