3

I use a pattern like the following in my generic architecture. It compiles and runs correctly in GCC 5.2.0:

#include <iostream>
using namespace std;


template<class Baz>
class Foo
{
public:
    void foo(){cout<<"Foo method";}
};


template<template<class> class FooType>
class BarBase: public FooType<int>
{
public:    
    double bar() {cout<<"Generic bar";}
};

template<template<class> class FooType>
class Bar: public BarBase<FooType>
{
};

template<>
class Bar<Foo>: public BarBase<Foo>
{
public:
    void specialBar(){cout<<"Specialized bar";}
};

struct Aspect_Foo
{
    template<class Baz>
    using FooTrait = Foo<Baz>;
};

struct Aspect_Bar
{    
    template<template<class> class FooType>
    using BarTrait = Bar<FooType>;
};


using Entity_NonAspectual = Bar<Foo>;


template<class FooAspect = Aspect_Foo,
         class BarAspect = Aspect_Bar>
using Entity_Aspectual = typename BarAspect::template BarTrait<
        FooAspect::template FooTrait>;


int main()
{  
  Entity_NonAspectual workingEntity;
  workingEntity.foo();
  workingEntity.bar();
  workingEntity.specialBar();

  Entity_Aspectual<> brokenEntity;

  brokenEntity.foo();
  brokenEntity.bar();
  brokenEntity.specialBar();
}

But in Clang 3.6, I get the following error message when calling brokenEntity.specialBar():

error: no member named 'specialBar' in 'Bar<FooTrait>'

Is this a compiler bug in Clang? Is there a workaround? Currently I'm pretty comfortable in Visual Studio 2013 with LLVM, and getting GCC to work with VS seems like a pain. I'm open to suggestions for alternative Windows-based IDE/compiler combinations as well.

WhittlesJr
  • 122
  • 8
  • 4
    I think there is a DR about the equivalence of alias templates with the templates they alias. That is, `FooTrait` might not be equivalent to `Foo`. -- edit: yes, that's [CWG 1286](http://wg21.cmeerw.net/cwg/issue1286) – dyp Aug 02 '15 at 19:34
  • 3
    [Minimal example that reproduces the issue](http://melpon.org/wandbox/permlink/f63rer5ea7wl1vWC). For g++, `A` is equivalent to `T`, while clang++ distinguishes between those two (for pattern matching in the full specialization of `TT`). – dyp Aug 02 '15 at 19:40
  • 1
    Regarding workarounds, the discussion here might help: http://stackoverflow.com/a/30654483/4326278. – bogdan Aug 02 '15 at 22:39

0 Answers0