template <class A>
struct Foo {
template <class Bar>
constexpr auto a_method();
};
template <class A>
template <class Bar>
constexpr auto Foo<A>::a_method() {
return 42;
}
template <>
template <class Bar>
constexpr auto Foo<void>::a_method() {
return 42;
}
Run Code Online (Sandbox Code Playgroud)
GCC可以编译这个。
但铿锵不能。错误输出:
<source>:15:27: error: conflicting types for 'a_method'
constexpr auto Foo<void>::a_method() {
^
<source>:4:18: note: previous declaration is here
constexpr auto a_method();
^
1 error generated.
Compiler returned: 1
Run Code Online (Sandbox Code Playgroud) 我的代码归结为以下内容:
template <typename T> struct Foo {};
template <typename T, const Foo<T>& I> struct FooBar {};
////////
template <typename T> struct Baz {};
template <typename T, const Foo<T>& I>
struct Baz< FooBar<T,I> >
{
static void func(FooBar<T,I>& value);
};
////////
struct MyStruct
{
static const Foo<float> s_floatFoo;
};
// Elsewhere: const Foo<float> MyStruct::s_floatFoo;
void callBaz()
{
typedef FooBar<float, MyStruct::s_floatFoo> FloatFooBar;
FloatFooBar myFloatFooBar;
Baz<FloatFooBar>::func(myFloatFooBar);
}
Run Code Online (Sandbox Code Playgroud)
这在GCC下成功编译,然而,在VS2005下,我得到:
error C2039: 'func' : is not a member of 'Baz<T>'
with
[
T=FloatFooBar
]
error …Run Code Online (Sandbox Code Playgroud) c++ templates compiler-errors visual-studio-2005 partial-specialization
可能重复:
部分模板特化的"无效使用不完整类型"错误
为什么我能做到这一点:
template <typename T>
struct A
{
void foo(int);
};
template <>
void A<int>::foo(int)
{
}
Run Code Online (Sandbox Code Playgroud)
但不是这个:
template <typename> struct C {};
template <typename T>
struct A
{
void foo(int);
};
template <typename T>
void A<C<T> >::foo(int)
{
}
Run Code Online (Sandbox Code Playgroud)
对于第二种情况,GCC给出以下错误:
test.cpp:10:23: error: invalid use of incomplete type 'struct A<C<T> >'
test.cpp:4:8: error: declaration of 'struct A<C<T> >'
Run Code Online (Sandbox Code Playgroud)
编辑:
在解释为什么不允许第二个例子时,请同时考虑使成员函数也是一个模板对哪个例子有效,哪个没有影响.也就是说,这仍然有效:
template <typename T>
struct A
{
template <typename U>
void foo(U);
};
template <>
template <typename U>
void …Run Code Online (Sandbox Code Playgroud) c++ templates partial-specialization template-specialization
不允许使用别名模板的部分特化:
例如,尝试创造性,在clang中产生此错误:
template <typename T>
using unwrapped_future_t = T;
template <typename T>
using unwrapped_future_t<future<T>> = typename future<T>::value_type;
^~~~~~~~~~~
> error: partial specialization of alias templates is not permitted
Run Code Online (Sandbox Code Playgroud)
为什么不允许这样做?
c++ templates partial-specialization template-specialization c++11
我有以下类结构
// file foo.h:
struct foo_base
{ ... }
template<typename T> struct foo : foo_base
{ ... };
template<typename F>
using is_foo = std::is_convertible<F,foo_base>;
template<typename, typename=void> struct aux;
template<typename Foo>
struct aux<Foo, typename std::enable_if<is_foo<Foo>::value>::type>
{ ... }; // specialisation for any foo
Run Code Online (Sandbox Code Playgroud)
// file bar.h:
#include "foo.h"
template<typename T> struct bar : foo<T>
{ ... };
template<typename T>
struct aux<bar<T>>
{ ... }; // specialisation for bar<T>
Run Code Online (Sandbox Code Playgroud)
现在,问题在于提供的aux<bar<T>>两种专业aux都是可行的.有没有办法避免这种歧义而不为每个人提供另一种专业化T?请注意,对文件的修改foo.h不得知道文件bar.h.
注意应解决歧义,以便 …
c++ templates partial-specialization template-specialization c++11
我曾经编写过一些代码,在编译时为一些模板元编程生成一个静态表/数组(想法是C样式的字符串可以在编译时构建(它们只是char数组)).这个想法和代码是基于David Lin的回答:
#include <iostream>
const int ARRAY_SIZE = 5;
template <int N, int I=N-1>
class Table : public Table<N, I-1>
{
public:
static const int dummy;
};
template <int N>
class Table<N, 0>
{
public:
static const int dummy;
static int array[N];
};
template <int N, int I>
const int Table<N, I>::dummy = Table<N, 0>::array[I] = I*I + 0*Table<N, I-1>::dummy;
template <int N>
int Table<N, 0>::array[N];
template class Table<ARRAY_SIZE>;
int main(int, char**)
{
const …Run Code Online (Sandbox Code Playgroud) c++ templates partial-specialization static-members language-lawyer
我正在尝试使用SFINAE专门为多种类型的结构模板.我知道类似以下的东西:
#include <iostream>
template <typename T, typename Enable = void>
struct S {
void operator()() {
std::cout << "Instantiated generic case" << std::endl;
}
};
template<typename T>
using enabled_type = typename std::enable_if<
std::is_same<T, int>::value ||
std::is_same<T, float>::value
>::type;
template <typename T>
struct S<T, enabled_type<T>> {
void operator()() {
std::cout << "Instantiated int/float case" << std::endl;
}
};
int main() {
S<float>()();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是我无法修改S
要添加的结构的主模板typename Enable = void,因为它是外部标头库的一部分.所以主模板必须如下所示:
template <typename T>
struct S {
void operator()() …Run Code Online (Sandbox Code Playgroud) 令我惊讶的是,当我尝试编译此代码时出现错误GCC 7.2.0.
码:
#include <typeinfo>
#include <iostream>
#include <utility>
template <typename Seq, typename Seq::value_type Inc> struct increment;
template <typename T, T... I, T Inc>
struct increment<std::integer_sequence<T,I...>, Inc> {
using type = std::integer_sequence<T,(I+Inc)...>;
};
int main(int argc, char* argv[]) {
typename increment<std::make_index_sequence<2>,1>::type seq;
std::cout << typeid(seq).name() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
错误:
error: partial specialization 'struct increment<std::integer_sequence<T, I ...>, Inc>' is not more specialized than [-fpermissive]
struct increment<std::integer_sequence<T,I...>, Inc> {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
spec.cc:5:62: note: primary template 'template<class Seq, typename Seq::value_type Inc> struct …Run Code Online (Sandbox Code Playgroud) 考虑:
#include <type_traits>
template <typename>
struct Tag {};
template <typename T>
auto tag = Tag<T>{};
template <typename...>
struct SelectorImpl;
// 1
template <auto... xs>
struct SelectorImpl<std::integral_constant<decltype(xs), xs>...>
{};
// 2
template <typename T, Tag<T>* tag, auto... xs>
struct SelectorImpl<std::integral_constant<decltype(tag), tag>,
std::integral_constant<decltype(xs), xs>...>
{};
template <auto... params>
struct Selector
: SelectorImpl<std::integral_constant<decltype(params), params>...>
{};
int main() {
Selector<&tag<int>, 1, 2>{};
}
Run Code Online (Sandbox Code Playgroud)
gcc和clang都无法编译它,报告这些特殊化SelectorImpl是不明确的.我相信专业化#2更专业.我错了吗?难道同样的问题,因为在这里?这是一个错误吗?
IMO,C++模板规则似乎限制太多,并且定义了编译器实现.但在这里,我有一个特定的行为,我很难缠绕我的脑袋.
在下面的问题中,我有意识地避免明确地专门化父类.
问题是,我可以部分专门化一个成员,但不能完全专门化.这实际上是反直觉的,因为您可以轻松地将虚拟模板添加到完全专用的模板中并使其部分专用.这里发生了什么??
重要的编辑:这很重要,因为,正如我们所知,你不能专门化成员函数而不专门化这个类(可以看作是这个问题的组合,需要部分专业化,而且c ++没有允许部分专门的函数.我不知道这些函数是否相关,但至少它们是一致的),因此如果你想在你的班级中使用一个你可以专攻的函数,你就会被使用仿函数所困扰.最重要的是,你需要添加一个虚拟模板参数,以使其工作!
这有效:
template <class T>
class A
{
template<typename Y, typename Z>
struct C{
void operator()(int x);
};
template<typename Z>
struct C<int, Z>{
void operator()(int x);
};
};
template <class T>
template <typename Z>
void A<T>::C<int, Z>::operator()(int x){
}
Run Code Online (Sandbox Code Playgroud)
但这不是:
template <class T>
class A
{
template<typename Y>
struct C{
void operator()(int x);
};
template<>
struct C<int>{
void operator()(int x);
};
};
template <class T>
template <>
void A<T>::C<int>::operator()(int x){
}
Run Code Online (Sandbox Code Playgroud)
编辑:Sean F.在评论中指出,编译器很难选择专业化.但问题在于,部分专业化不会使问题消失.所以这不是答案.
c++ templates partial-specialization rationale template-specialization