2013-04-15 2 views
1

Похоже, что сбой замены иногда является ошибкой.
Может ли кто-нибудь сказать мне, когда это будет ошибка, а когда нет?
Просмотреть результат поиска here
Спасибо!Ошибка замещения иногда является ошибкой

Благодарим вас за информативный ответ!
Этот код не компилируется с g ++ 4.8, но работает как ожидается с помощью clang ++ 3.2, g ++ 4.7.3 и intel 13.0.1. Итак, теперь я уверен, что это ошибка для g ++ 4.8. Я сообщил об этом gcc bugzila.

In substitution of ‘template<class C> static constexpr int has<T>::test(decltype (sizeof (C:: x))) [with C = C; T = foo] [with C = foo]’: 
required from ‘const int has<foo>::value’ 
required from here 
error: invalid use of non-static member function ‘std::string foo::x()’ 

Код

template <typename T> 
struct has { 
    template <typename> 
    constexpr static int test(...) { 
     return 0; 
    } 
    template <typename C> 
    constexpr static int test(decltype(sizeof(C::x))) { // Doesn't compile. 
     return 1; // Is a member variable. 
    } 
    template <typename C, int c = 
     sizeof(decltype(((C*)nullptr)->x()))> 
    constexpr static int test(int) { 
     return 2; // Is a member function. 
    } 
    static const int value = test<T>(0); 
}; 

struct foo { 
    string x(); 
}; 
struct bar { 
    string x; 
}; 
int main() { 
    std::cout << has<int>::value << std::endl; 
    std::cout << has<foo>::value << std::endl; 
    std::cout << has<bar>::value << std::endl; 
} 
+0

Ваша ошибка «неправильное использование нестатической функции члена„станд :: строка Foo :: х()“», так что проблема идет от метод не является статичным при попытке доступа к нему статическим способом. – Geoffroy

+0

Работы на Clang 3.2 Я считаю, что это ошибка –

ответ

4

правило, по существу, что ошибка должна зависеть от параметра шаблона декларации, который немедленно принадлежит.

Этот пример выглядит как ошибка компилятора. Это неверно, а не ошибка из-за конкретного недостатка синтаксиса.

Если вы хотите, чтобы вернуть успех, когда класс имеет нестатическую функцию-член с именем x, вы должны использовать &C::x, потому что вы позволили взять указатель на функцию-члена, но не просто назвать его как автономное подвыражение ,

Мой предпочтительный способ сделать это было бы

template< typename, typename = void > 
struct has_x 
    : std::false_type {}; 

template< typename t > 
struct has_x< t, typename std::enable_if< & t::x == & t::x >::type > 
    : std::true_type {}; 
+0

Действительно. Код работает, как ожидалось, с clang ++ 3.2 – yufanyufan

+0

Я расширяю свой код еще немного. Я хочу проверить, является ли данное имя переменной-членом или функцией-членом. – yufanyufan

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