How to prevent non-specialized template instantiat

2019-01-11 03:08发布

I have a templated class (call it Foo) which has several specializations. I would like the compilation to fail if someone tries to use an unspecialized version of Foo.

Here is what I actually have:

template <typename Type>
class Foo
{
  Foo() { cannot_instantiate_an_unspecialized_Foo(); }

  // This method is NEVER defined to prevent linking.
  // Its name was chosen to provide a clear explanation why the compilation failed.
  void cannot_instantiate_an_unspecialized_Foo();
};

template <>
class Foo<int>
{    };

template <>
class Foo<double>
{    };

So that:

int main()
{
  Foo<int> foo;
}

Works while:

int main()
{
  Foo<char> foo;
}

Does not.

Obviously, the compiler chain only complains when the linking process takes place. But is there a way to make it complain before ?

I can use boost.

3条回答
我命由我不由天
2楼-- · 2019-01-11 03:23

Just don't define the class:

template <typename Type>
class Foo;

template <>
class Foo<int> { };

int main(int argc, char *argv[]) 
{
    Foo<int> f; // Fine, Foo<int> exists
    Foo<char> fc; // Error, incomplete type
    return 0;
}

Why does this work? Simply because there isn't any generic template. Declared, yes, but not defined.

查看更多
家丑人穷心不美
3楼-- · 2019-01-11 03:25

A trick for C++0x (also available with a C++03 static_assert emulation, but the error message isn't necessarily better than leaving the primary template undefined):

template<typename T>
struct dependent_false: std::false_type {};

template<typename Type>
struct Foo {
    static_assert( dependent_false<Type>::value
                 , "Only specializations of Foo may be used" );
};

The assertion will only trigger when Foo is instantiated with the primary template. Using static_assert( false, ... ) would trigger the assertion all the time.

查看更多
太酷不给撩
4楼-- · 2019-01-11 03:29

You can simply not define the base case:

template <typename> class Foo;             // no definition!

template <> class Foo<int> { /* ... */ };  // Foo<int> is OK
查看更多
登录 后发表回答