2017-03-20 9 views
1

私はstatic_assertの仕組みを理解していると思っています。私はG ++コンパイラでこれをしようとしたときしかし、私は疑問に思い始めた:メンバテンプレートがインスタンス化されていない場合、static_assertを評価しますか?

#include <iostream> 
#include <type_traits> 

#define ENABLE_IF(...) std::enable_if_t<__VA_ARGS__, int> = 0 

template<typename...Ts> 
struct list{}; 

template<typename...Ts> 
struct is_one_of; 

template<template <typename...> class TT, typename T, typename T1, typename...Ts> 
struct is_one_of<T, TT<T1, Ts...>> : is_one_of<T, TT<Ts...>> {}; 

template<template <typename...> class TT, typename T, typename...Ts> 
struct is_one_of<T, TT<T, Ts...>> : std::true_type {}; 

template<template <typename...> class TT, typename T> 
struct is_one_of<T, TT<>> : std::false_type {}; 


template<typename...Ts> 
struct X; 

template<typename P, typename T, typename...Ts> 
struct X<P, T, Ts...> : X<P, Ts...> 
{ 
    using X<P, Ts...>::fn; 

    template<typename R, ENABLE_IF(std::is_same<T, R>::value)> 
    constexpr auto fn(R&& x) 
    { 
    return x; 
    } 
}; 

template<template <typename...> class TT, typename...Ts> 
struct X<TT<Ts...>> 
{ 
    template<typename R, ENABLE_IF(!is_one_of<R, TT<Ts...>>::value)> 
    constexpr auto fn(R&& x) 
    { 
    static_assert(false, "Type R didn't match"); 
    } 
}; 


template<typename...Ts> 
struct XX : X<list<Ts...>, Ts...> {}; 


int main() { 
    XX<int, float> x; 
    std::cout << x.fn(int(3)) << std::endl; 
    return 0; 
} 

今、私はそれが呼ばれることはありませんので、基本型X<TT<Ts...>>が今までインスタンス化されている可能性があることどのような方法がないだろうと思っているだろう。このような理由から、エラーが発生しないようにしてください。static_assert

これはグラムで失敗++(5.4.0)と打ち鳴らす(3.9.1)が、VC++で働いていた2015年

欠陥または私は何かが欠けています。このですか? [temp.res]のそれは抵触実行されるため、static_assert(false)を書く

答えて

4

は、単に病気-形成されている:

プログラムがあれば、必要な一切の診断、病気に形成されていない:
- 有効な分業はなることはできませんテンプレートまたはテンプレート内constexpr if書(6.4.1)のサブステートメントのために生成されたテンプレートが

をインスタンス化されていない あなたはと考えることができ

からstatic_assertの定数式が依存しないので、コンパイラはすぐにそれが悪いと火災を参照してください。でも、有効な分業を生成するためにこれは、それが仮に可能になるだろう

template <class T> struct always_false : std::false_type { }; 
static_assert(always_false<some_dependent_type>::value, "..."); 


あなたはどちらかだけで専門のためfn()の定義を提供することができない、またはあなたのような何かを行うことができます誰も特別なことがなければalways_false

関連する問題