Возможная ошибка компилятора Visual Studio C++? Проблема с нетиповым параметром шаблона
Новый вопрос
редактировать
Эта ошибка, кажется, такая же, как эта:
MSVC отклоняет следующий код:
template <template <typename T, typename T::mytype x> class X>
struct z
{};
template <typename T, typename T::mytype xx>
struct x
{};
z<x> zz;
ошибка C3201: список параметров шаблона для шаблона класса 'x' не соответствует списку параметров шаблона для параметра шаблона 'X'
Но шаблон класса x имеет тот же набор параметров шаблона, что и параметр X.
Ад! Это сообщение об ошибке с апреля 2012 года?!
С
Статус: закрыт как отложенный
:(
Microsoft, я разочарован TT
редактировать редактировать
В моем случае (ниже) я могу взломать мой способ сделать то, что я хочу, но это ужасно:
//Library code
struct Boundary {
double sup, inf;
};
template <
class UserBoundaries,
template <size_t, bool...> class LocalInfo,
size_t hack>
struct Space_LocalParameters : LocalInfo<hack> {};
//User code
struct Boundaries_Problem7 {
Boundary b1, b2, b3;
};
template <size_t, bool...>
struct LocalInfo_Problem7 {};
template <size_t hack, bool... args>
struct Problem7_Functions
: Space_LocalParameters < Boundaries_Problem7, LocalInfo_Problem7, hack, args...> {};
int main() {}
Использование:
//Compute the offset of member b2 in Boundaries_Problem7
const size_t hack = (size_t)(&((Boundaries_Problem7*)0)->b2);
if (...)
problem.functions[k].SetFunction(&Problem7_Functions<hack, true, false>::f);
else if (...)
problem.functions[k].SetFunction(&Problem7_Functions<hack, false, true>::f);
else problem.functions[k].SetFunction(&Problem7_Functions<hack, false, false>::f);
//Later in that function
if (boundary_Inf) {
value += this->points[0].coef
* ((Boundary*)((char*)&domain.boundaries + hack))->inf;
}
if (boundary_Sup) {
value += this->points[N-1].coef
* ((Boundary*)((char*)&domain.boundaries + hack))->sup;
}
Разрешено ли компилятору изменять смещение элемента при оптимизации?
конец редактирования
Новый вопрос
Следующее прекрасно компилируется на http://coliru.stacked-crooked.com/a/be088e06861f9349
//Library code
struct Boundary {};
template <
class UserBoundaries,
template <Boundary UserBoundaries::*> class LocalInfo,
Boundary UserBoundaries::*m_ptr>
struct Space_LocalParameters : LocalInfo<m_ptr> {};
//User code
struct Boundaries_Problem7 {
Boundary b1, b2, b3;
};
template <Boundary Boundaries_Problem7::*m_ptr>
struct LocalInfo_Problem7 {};
template <Boundary Boundaries_Problem7::*ptr>
struct Problem7_Functions
: Space_LocalParameters < Boundaries_Problem7, LocalInfo_Problem7, ptr> {}; // <-- C3201
int main() {}
Но Visual Studio 2013 дает мне эту ошибку:
ошибка C3201: список параметров шаблона для шаблона класса "LocalInfo_Problem7" не соответствует списку параметров шаблона для параметра шаблона "LocalInfo"
Это ошибка компилятора VS? Или мой код неверен?
Я написал отчет об ошибке здесь https://connect.microsoft.com/VisualStudio/feedback/details/933984/c-visual-studio-2013-compiler-bug-template-template-pointer-to-member-issue
Если это ошибка, как я могу заставить это работать?
Спасибо за вашу помощь.
Старый вопрос
У меня проблемы с довольно сложным шаблоном "typedef".
Чтобы максимально упростить проблему, я придумал это:
template <class A, template <A*> class B, A* ptr>
struct Foo : B<ptr> {};
template <class, class AA, template <AA*> class BB, AA* ptr>
using Bar = Foo<AA, BB, ptr>; // <-- C3201
Visual Studio 2013 дает мне: ошибка C3201: список параметров шаблона для шаблона класса "BB" не соответствует списку параметров шаблона для параметра шаблона "B"
Я не вижу, что не так.
Foo<AA, BB, ptr>
"расширяется до" template <class AA, template <AA*> class BB, AA* ptr> struct Foo : BB<ptr> {}
Теоретически, если мы определим следующее (я на самом деле не пытался скомпилировать следующее):
class MyClass {} myClass_instance;
template <MyClass*> class MyTemplateClass {};
затем
Bar<whatever, MyClass, MyTemplateClass, &myClass_instance>
должен быть псевдонимом для
Foo<MyClass, MyTemplateClass, &myClass_instance> : MyTemplateClass<&myClass_instance>
Это выглядит нормально для меня.
Любопытно, что два следующих варианта компилируются нормально:
1 / Изменение template <A*>
а также template <AA*>
с template <Z*>
class Z;
template <class A, template <Z*> class B, A* ptr>
struct Foo : B<ptr> {};
template <class, class AA, template <Z*> class BB, AA* ptr>
using Bar = Foo<AA, BB, ptr>;
Этот обходной путь позволил моей программе работать нормально, но это побило цель моего шаблонного подхода.
Или 2/ Удаление первого параметра шаблона Bar
template <class A, template <A*> class B, A* ptr>
struct Foo : B<ptr> {};
template <class AA, template <AA*> class BB, AA* ptr>
using Bar = Foo<AA, BB, ptr>;
Так в чем же несоответствие, упомянутое компилятором?
Почему удаление первого параметра шаблона Bar решает проблему?
Спасибо за вашу помощь.