C ++容器内容特征混淆
c++ container contents traits confusion
我希望能够 select 一个不同的 class 在编译时根据容器内容的类型实例化 class。 Clang 和 GCC 都给出了下面代码的错误,所以我预计它有问题,即使它使用 Visual Studio 的行为是正确的。有什么想法吗?
#include <iostream>
template <bool, class T = void>
struct enable_if {};
template <class T>
struct enable_if<true, T> {
typedef T type;
};
struct a {};
struct b {};
struct a_container {
typedef a contents_type;
};
struct b_container {
typedef b contents_type;
};
template <class T>
struct is_an_a { enum { value = false }; };
template <>
struct is_an_a<a> { enum { value = true }; };
template <class container_type>
struct container_traits {
typedef typename container_type::contents_type value_type;
};
template <class container_type>
struct is_an_a_container {
enum { value = typename is_an_a<typename container_traits<container_type>::value_type>::value };
};
template<class container_type, class enable = void>
struct S {
void operator()() {
std::cout << "Not an A\n";
}
};
template<class container_type>
struct S<container_type, typename enable_if<is_an_a_container<container_type>::value>::type> {
void operator()() {
std::cout << "Got an A\n";
}
};
int main() {
S<a_container>()();
S<b_container>()();
return 0;
}
从Visual Studio开始,输出为:
Got an A
Not an A
GCC 失败:
35: error: expected `(' before '}' token
虽然 Clang 失败了:
35 : error: expected '(' for function-style cast or type construction
我可以通过将 is_an_a_container
的定义内联到 S
的第二个版本(例如下面)来解决这个问题,但在我看来它有点晦涩,我想了解错误。
template<class container_type>
struct S<container_type, typename enable_if<is_an_a<typename container_traits<container_type>::value_type>::value>::type> {
void operator()() {
std::cout << "Got an A\n";
}
};
或者也许有更简洁的解决方案来实现目标?注意:我必须使用 container_traits
.
template <class container_type>
struct is_an_a_container {
enum { value = typename is_an_a<typename conntainer_traits<container_type>::value_type>::value };
^^^^^^^^ ^^^^^ // this is not a type
};
只需删除类型名称
template <class container_type>
struct is_an_a_container {
enum { value = is_an_a<typename conntainer_traits<container_type>::value_type>::value };
};
我希望能够 select 一个不同的 class 在编译时根据容器内容的类型实例化 class。 Clang 和 GCC 都给出了下面代码的错误,所以我预计它有问题,即使它使用 Visual Studio 的行为是正确的。有什么想法吗?
#include <iostream>
template <bool, class T = void>
struct enable_if {};
template <class T>
struct enable_if<true, T> {
typedef T type;
};
struct a {};
struct b {};
struct a_container {
typedef a contents_type;
};
struct b_container {
typedef b contents_type;
};
template <class T>
struct is_an_a { enum { value = false }; };
template <>
struct is_an_a<a> { enum { value = true }; };
template <class container_type>
struct container_traits {
typedef typename container_type::contents_type value_type;
};
template <class container_type>
struct is_an_a_container {
enum { value = typename is_an_a<typename container_traits<container_type>::value_type>::value };
};
template<class container_type, class enable = void>
struct S {
void operator()() {
std::cout << "Not an A\n";
}
};
template<class container_type>
struct S<container_type, typename enable_if<is_an_a_container<container_type>::value>::type> {
void operator()() {
std::cout << "Got an A\n";
}
};
int main() {
S<a_container>()();
S<b_container>()();
return 0;
}
从Visual Studio开始,输出为:
Got an A
Not an A
GCC 失败:
35: error: expected `(' before '}' token
虽然 Clang 失败了:
35 : error: expected '(' for function-style cast or type construction
我可以通过将 is_an_a_container
的定义内联到 S
的第二个版本(例如下面)来解决这个问题,但在我看来它有点晦涩,我想了解错误。
template<class container_type>
struct S<container_type, typename enable_if<is_an_a<typename container_traits<container_type>::value_type>::value>::type> {
void operator()() {
std::cout << "Got an A\n";
}
};
或者也许有更简洁的解决方案来实现目标?注意:我必须使用 container_traits
.
template <class container_type>
struct is_an_a_container {
enum { value = typename is_an_a<typename conntainer_traits<container_type>::value_type>::value };
^^^^^^^^ ^^^^^ // this is not a type
};
只需删除类型名称
template <class container_type>
struct is_an_a_container {
enum { value = is_an_a<typename conntainer_traits<container_type>::value_type>::value };
};