Compile pattern type matching at compile time

I have this template class:

template <class Tin, class Tout>
class Foo
{
    Tin input;
    Tout output;

    static inline void __ensure_type_consistency
    {
        int16_t* p = (int16_t *)0;
        // uint16_t* p1 = p;
        Tin* check_type_in = p;
        Tout* check_type_out = p;  
    }
public:
    ...
}

I want to make sure Tin, and Toutboth types of typedef'd gain int16_trather than any other type. ( NOTE: read the full question before proceeding to the conclusions)

If I uncomment the commented line, I get the error as expected; the compiler does not allow to assign pointers of different types to each other without casting:

"src\foo.h", line 47: error #145: a value of type "int16_t *" 
cannot be used to initialize an entity of type "uint16_t *"

But if I leave it commented out and I create an instance:

Foo<uint16_t, int32_t> illegalFoo;

I don't get compiler errors, although the same type of check is used (creating an incompatible pointer assignment in a static function that never gets called, but which should cause compiler errors)

? , , ?

. . "" , , typedefs : , Foo.input Tin, Tin int16_t, typedef, int16_t, Foo.output Tout. , typedef'd , ++ .


edit:, , , Boost. ++ 0x.

+3
6

:

template <class, class> class Foo;

template <>
class Foo<int16_t, int16_t> {
  ...
};

, , BOOST_STATIC_ASSERT Boost static_assert ++ 0x. , Boost ++ 0x , , :

(void)(true ? (int16_t**)0 : (Tin**)0);

Tout. - , , ( Boost.Concept_check). - is_same/static_assert, , Boost ++ 0x, :

template <class, class> struct types_valid {static const int value = -1;};
template <> struct types_valid<int16_t, int16_t> {static const int value = 1;};

static char foo[types_valid<Tin, Tout>::value]; . , foo, -.

+4

is_same static_assert. ++ 0x :

static_assert(std::is_same<Tin, std::int16_t>::value &&
              std::is_same<Tout, std::int16_t>::value, "o noez");

is_same static Boost. , Boost, .

+5

boost ++ 1x, is_same

// Beware, brain-compiled code ahead!
template< typename T1, typename T2>
struct is_same      { static const bool result = false; };

template< typename T > 
struct is_same<T,T> { static const bool result = true; };

template< bool Condition, typename Dummy = void >
struct static_assert {
  typedef bool result;
};

template<typename IntentionalError>
struct static_assert<false,IntentionalError> {
  typedef typename IntentionalError::does_not_exist result;
};

:

template <class Tin, class Tout>
class Foo
{
    Tin input;
    Tout output;

    typedef typename static_assert<is_same<Tin ,int16_t>::result>::result Tin_test;
    typedef typename static_assert<is_same<Tout,int16_t>::result>::result Tout_test;
    typedef typename static_assert<is_same<Tout,Tout   >::result>::result Tout_test;
// ...
};
+2

, __ensure_type_consistency() -, . , , .

V++ 2010, .


GCC? (()) __ensure_type_consistency.

+2
source

You can use boost checks:

BOOST_CONCEPT_ASSERT((boost::Integer<Tin>));
BOOST_CONCEPT_ASSERT((boost::Integer<Tout>));

See http://www.boost.org/doc/libs/1_45_0/libs/concept_check/using_concept_check.htm

0
source

I adapted a few answers to this question, and this seems like a trick:

Helper class:

template <typename T1, typename T2>
struct TypeConsistency
{
private:
    static inline void checkfunction()
    {
        T1* p1 = (T1 *)0;
        T2* p2 = p1;
    }
public:
    static inline void check() { checkfunction; }
    /* The above line does nothing at runtime,
     * but takes the address of checkfunction(),
     * which causes a compile-time type check.
     */ 
};

Applying this in my foo class:

template <class Tin, class Tout> 
class Foo
{
    Tin input;
    Tout output;

public:
    Foo() { 
        TypeConsistency<int16_t, Tin>::check();
        TypeConsistency<int16_t, Tout>::check();
    }
    ...
}
0
source

Source: https://habr.com/ru/post/1787491/


All Articles