2014-12-14 2 views
3

На мой вопрос type as returntype in c++ я был предоставлен ответ, который дал мне такую ​​структуру:«используя тип» в C++ вызывает несколько ошибок

template <int N> 
struct int_type { 
    using type = std::conditional_t<N <= 8, std::uint8_t, 
       std::conditional_t<N <= 16, std::uint16_t, 
       std::conditional_t<N <= 32, std::uint32_t, 
       std::conditional_t<N <= 64, std::uint64_t, 
       std::uintmax_t>>>>; 
}; 

Это казалось сделать excactly то, что мне нужно, как никогда практика выглядит по-другому, так как я не могу скомпилировать его из-за следующие ошибки:

...Error: expected nested-name-specifier before 'type' 
using type = std::conditional_t<N <= 8, std::uint8_t, 
    ^
...Error: using-declaration for non-member at class scope 
...Error: expected ';' before '=' token 
using type = std::conditional_t<N <= 8, std::uint8_t, 
      ^
...Error: expected unqualified-id before '=' token 

Я попытался Google, но ни один из постов, которые я нашел, кажется, адресовать эти конкретные проблемы. Может ли кто-нибудь объяснить мне, что не так с этим кодом? Я довольно новичок в C++

+0

'conditional_t' - это вспомогательный тип, введенный в C++ 14. Вы компилируете флаг '-std = C++ 14'? – vsoftco

+1

@PeterT вот что, 'std :: conditional_t' является typedef для' условного :: типа' http://en.cppreference.com/w/cpp/types/conditional – vsoftco

+0

@vsoftco мой плохой, я должен " я прочитал это более внимательно – PeterT

ответ

2

Ваш код является совершенно законным, пока ваш компилятор поддерживает C++ 14 STDLIB-х <type_traits>, которые определяют шаблон для псевдонима std::conditional признака.

Однако сообщение об ошибке ясно указывает, что вы даже не включили C++ 11, поэтому using не анализируется как псевдоним вообще. Для этого добавьте опцию -std=c++11 или -std=c++14 к вашей конфигурации.

Если вы не можете, то в C++ 03 вы можете легко реализовать свою собственную conditional особенности:

template <bool B, typename T, typename F> 
struct conditional 
{ 
    typedef T type; 
}; 

template <typename T, typename F> 
struct conditional<false, T, F> 
{ 
    typedef F type; 
}; 

template <int N> 
struct int_type { 
    typedef typename conditional<N <= 8, uint8_t, 
       typename conditional<N <= 16, uint16_t, 
       typename conditional<N <= 32, uint32_t, 
       typename conditional<N <= 64, uint64_t, 
       uintmax_t>::type>::type>::type>::type type; 
}; 

В C++ 11 вы можете использовать std::conditional вместо std::conditional_t, единственное отличие состоит в том, что вам необходимо получить доступ к вложенному ЬурейеМу type на своем собственном, который является зависимым именем (typename ключевым слова необходимо перед вложенного имени спецификатор):

#include <cstdint> 
#include <type_traits> 

template <int N> 
struct int_type { 
    using type = typename std::conditional<N <= 8, std::uint8_t, 
       typename std::conditional<N <= 16, std::uint16_t, 
       typename std::conditional<N <= 32, std::uint32_t, 
       typename std::conditional<N <= 64, std::uint64_t, 
       std::uintmax_t>::type>::type>::type>::type; 
}; 

В C++ 11/C++ 14 вам необходимо включить <cstdint> вместо <stdint.h>. Первые гарантируют, что имена определены в пространстве имен std (последние могут определять их только в пространстве имен).

+0

спасибо =) Хорошего дня. – TreeOfLife

-1

Да, когда вы делаете typedef, компилятор сообщает вам, что не так. Это зависимые имена, поэтому вам нужно «typename» перед ним. поэтому это должно работать:

#include <iostream> 
#include <type_traits> 
using namespace std; 

template <int N> 
struct int_type { 
    using mytype = typename std::conditional<N <= 8, std::uint8_t, 
        typename std::conditional<N <= 16, std::uint16_t, 
         typename std::conditional<N <= 32, std::uint32_t, 
         typename std::conditional<N <= 64, std::uint64_t, 
          std::uintmax_t 
         >::type 
         >::type 
        >::type 
        >::type; 
}; 
+1

'std :: conditional_t' не является typedef, а шаблон-псевдоним, он добавляет' typename' самостоятельно в определении –

+0

@PiotrS. Я имею в виду, что я написал 'typedef std :: conditional <...> type;' и он показал другую ошибку – PeterT

+1

, удалив первую часть вашего ответа, но, тем не менее, ошибка не указывает на невозможность компилятора разрешить зависимое имя, поддержка псевдонимов –

0

Я добавлю здесь ответ ради полноты.

Необходимо выполнить #include <cstdint> и #include <type_traits>, а затем скомпилировать с поддержкой C++ 14. Код:

#include <type_traits> 
#include <cstdint> 
#include <iostream> 

template <int N> 
struct int_type { 
    using type = std::conditional_t<N <= 8, std::uint8_t, 
       std::conditional_t<N <= 16, std::uint16_t, 
       std::conditional_t<N <= 32, std::uint32_t, 
       std::conditional_t<N <= 64, std::uint64_t, 
       std::uintmax_t>>>>; 
}; 

int main() 
{ 
    int_type<10>::type t; // std::uint16_t 
    t = 12; 
    std::cout << t << std::endl; 
} 

Живой пример: http://coliru.stacked-crooked.com/a/9352f3349f48bff4

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