2016-05-28 2 views
4

У меня есть следующий сокращенный код.
Линия с // Only VS компилируется на VS, но не на clang,
И линия с // Only clang компилируется на clang, но не на VS.
Кто такой человек? Что еще более важно, как создать эквивалентную линию для обоих?
Версии Испытуемые лязг 3.7.0 и VS 2015.Не удается получить шаблоны для компиляции под Visual Studio и clang

#include <functional> 
#include <tuple> 

template<typename... Args> 
class C 
{ 
    struct B 
    { 
     std::function<void(Args...)> func; 
     B(std::function<void(Args...)> func) : func(func) { } 
    }; 
    template<typename T> 
    struct D : B 
    { 
     using B::B; 
     template<size_t... I> 
     void Call(T &t, std::index_sequence<I...>) 
     { 
      func(std::get<I>(t)...); // Only VS 
      B::template func(std::get<I>(t)...); // Only clang 
     } 
    }; 
    D<std::tuple<Args...>> d; 
public: 
    C(std::function<void(Args...)> func) : d(func) { } 
    void Call() 
    { 
     std::tuple<Args...> t; 
     d.Call(t, std::make_index_sequence<sizeof...(Args)>()); 
    } 
}; 

void f(int) 
{ 

} 

int main() 
{ 
    C<int> c(f); 
    c.Call(); 
} 
+1

Как насчет 'this-> func (std :: get (t) ...);'? – Flexo

+0

@Flexo: Это действительно работает, но почему? – Dani

+1

'this-> func (std :: get (t) ...);' или 'B :: func (std :: get (t) ...);' должен работать, 'B :: шаблон func (std :: get (t) ...); 'недопустимо, потому что' func' не является шаблоном –

ответ

4

Я думаю, что оба не правы. Для первого использования func(...) - это неквалифицированное имя, которое просматривается с использованием зависимого от аргумента поиска, который не находит функцию в базовом классе. Использование B::template func(...) использует избыточное ключевое слово template. Вы можете заставить смотреть план func в контексте класса с использованием

this->func(...); 

this-> заставляет необходимый контекст. Я думаю, B::func(...) также должен работать, но я использую this->func(...) в подобных ситуациях.

Я считаю, что соответствующая оговорка 14.6.2 [temp.dep] пункт 3:

В определении шаблона класса или класса, объем зависимого базового класса (14.6.2.1) является не проверяется при поиске неквалифицированного имени либо в точке определения шаблона класса или члена, либо во время создания шаблона или члена класса.

Проблема в том, что B зависит от аргументов шаблона охватывающего класса. Присвоение имени this-> или поиск имени базового класса в контексте базового класса.

+0

Прежде чем искать с зависимым от аргумента, он должен искать 'func', как если бы он был членом базового класса и нашел его. – Dani

+4

Нет, не для шаблонов классов. Шаблоны классов обычно не выглядят в их базовых классах, если поиск в базе не принужден к какой-либо форме квалификации ('B ::' или 'this->'). –

Смежные вопросы